home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Cl… (Business) 1997 November / Software of the Month Club - Business Shareware (Volume 243) (November 1997).iso / dos / biz / Parse / MANUAL.TXT < prev    next >
Encoding:
Text File  |  1997-08-27  |  411.4 KB  |  11,169 lines

  1.     ===========================================================================
  2.     ===========================================================================
  3.     ============================                   ============================
  4.     ============================                   ============================
  5.     ============================   PARSE-O-MATIC   ============================
  6.     ============================                   ============================
  7.     ============================                   ============================
  8.     ===========================================================================
  9.     ===========================================================================
  10.  
  11.  
  12.               Copyright (C) 1986, 1997 by Pinnacle Software (Montreal)
  13.  
  14.  
  15.     +-------------------------- WIDE APPLICABILITY ---------------------------+
  16.     |                                                                         |
  17.     |                                                                         |
  18.     |          Runs under MS-DOS, Windows (3.1 or 95), Novell & OS/2          |
  19.     |                                                                         |
  20.     |          Can be invoked by other DOS, Windows or OS/2 programs          |
  21.     |          such as FoxPro, Pascal, Visual Basic, C++, Delphi and          |
  22.     |          so on, with success verification (return code or log)          |
  23.     |                                                                         |
  24.     |          Can be run under DOS emulators (e.g. Macintosh, Unix)          |
  25.     |          for convenient cross-platform conversion.                      |
  26.     |                                                                         |
  27.     |                                                                         |
  28.     +------- HERE ARE A FEW OF THE THINGS PARSE-O-MATIC CAN DO FOR YOU -------+
  29.     |                                                                         |
  30.     |                                                                         |
  31.     |      Importing             Exporting             Automated Editing      |
  32.     |      Text Extraction       Data Conversion       Table Lookup           |
  33.     |      Retabulation          Info Weeding          Selective Copying      |
  34.     |      Binary-File to Text   Report Reformatting   Wide-Text Folding      |
  35.     |      Auto-Batch Creation   Comm-log Trimming     Tab Replacement        |
  36.     |      Character Filtering   Column Switching      DBF Interpretation     |
  37.     |      De-uppercasing        Name Properization    And much more!         |
  38.     |                                                                         |
  39.     |                                                                         |
  40.     +---- INPUT AND OUTPUT METHODS CURRENTLY SUPPORTED BY PARSE-O-MATIC ------+
  41.     |                                                                         |
  42.     |                                                                         |
  43.     |   Input:  Text (any format), Binary, DBF (DBase), Fixed-Record-Length,  |
  44.     |           Variable-Record-Length, EBCDIC                                |
  45.     |                                                                         |
  46.     |  Output:  Text (e.g. flat, comma-delimited, paginated, hex), Binary,    |
  47.     |           Fixed-Record-Length, Variable-Record-Length, EBCDIC,          |
  48.     |           Generic output devices (e.g. COM1: or LPT2:)                  |
  49.     |                                                                         |
  50.     |                                                                         |
  51.     +-------------------------------------------------------------------------+
  52.  
  53.  
  54.  
  55.  
  56.  
  57.     +------------ UNSOLICITED TESTIMONIALS (USED WITH PERMISSION) ------------+
  58.     |                                                                         |
  59.     |                                                                         |
  60.     |   "Parse-O-Matic is absolutely great.  I use it when I collect data     |
  61.     |   from the McDonald's restaurants in Switzerland.  POM has paid for     |
  62.     |   itself so many times ..." -- Chris Friedli                            |
  63.     |                                                                         |
  64.     |                                                                         |
  65.     +-------------------------------------------------------------------------+
  66.     |                                                                         |
  67.     |                                                                         |
  68.     |   "Parse-O-Matic is a wonderful time saver .... Each report that I      |
  69.     |   can convert from our ... accounting system saves our company about    |
  70.     |   500 man hours per year." -- R. Brooker                                |
  71.     |                                                                         |
  72.     |                                                                         |
  73.     +-------------------------------------------------------------------------+
  74.     |                                                                         |
  75.     |                                                                         |
  76.     |   "In 30 years of working with computers, this is by far the easiest    |
  77.     |   way I have found to extract data from files.  I was very surprised    |
  78.     |   that the program just took a few seconds to chew its way through      |
  79.     |   1MB of data.  You ought to mention it's FAST." -- Koenraad Rutgers    |
  80.     |                                                                         |
  81.     |                                                                         |
  82.     +-------------------------------------------------------------------------+
  83.     |                                                                         |
  84.     |                                                                         |
  85.     |   "Parse-O-Matic is THE greatest parsing package .... I wrote my own    |
  86.     |   software for parsing ... then I was introduced to POM and have been   |
  87.     |   using it ever since.  Good job!" -- Jeff Tallent, Vestax Securities   |
  88.     |                                                                         |
  89.     |                                                                         |
  90.     +-------------------------------------------------------------------------+
  91.  
  92.  
  93.  
  94.  
  95.     +---------------------- PARSE-O-MATIC IS VERSATILE -----------------------+
  96.     |                                                                         |
  97.     |                                                                         |
  98.     |                                                                         |
  99.     |    This manual was formatted by Parse-O-Matic, from plain text files.   |
  100.     |        The table of contents was also generated by Parse-O-Matic.       |
  101.     |                                                                         |
  102.     |                                                                         |
  103.     |                                                                         |
  104.     +-------------------------------------------------------------------------+
  105.  
  106.  
  107.  
  108.  
  109.     +------------------------ WHO USES PARSE-O-MATIC? ------------------------+
  110.     |                                                                         |
  111.     |                                                                         |
  112.     |              Some of our distinguished customers include:               |
  113.     |                                                                         |
  114.     |                                                                         |
  115.     |  Bankers Trust           HBO (Home Box Office)   Philip Morris          |
  116.     |                                                                         |
  117.     |  Berliner Volksbank      Harris Semiconductor    Pitney Bowes           |
  118.     |                                                                         |
  119.     |  Boeing                  Home Box Office         Prentice Hall          |
  120.     |                                                                         |
  121.     |  Bridgestone             Hughes                  Procter and Gamble     |
  122.     |                                                                         |
  123.     |  CIBA Vision             Ingram                  Rank Xerox             |
  124.     |                                                                         |
  125.     |  Calcomp Canada          Carrefour France        Kodak                  |
  126.     |                                                                         |
  127.     |  Royal Bank              Champion Int'l          Lipton Tea             |
  128.     |                                                                         |
  129.     |  Royal Caribbean         CompUSA                 May Department Stores  |
  130.     |                                                                         |
  131.     |  SmithKline Beacham      Degussa                 McCain Foods           |
  132.     |                                                                         |
  133.     |  Southwest Bancorp       Dresdner Bank           McDonald's             |
  134.     |                                                                         |
  135.     |  Sun Life                Eaton                   Monsanto France        |
  136.     |                                                                         |
  137.     |  Sundstrand Aerospace    Eddy                    NEC                    |
  138.     |                                                                         |
  139.     |  Target                  European American Bank  Nestle                 |
  140.     |                                                                         |
  141.     |  Visa International      First Bank System       Nike                   |
  142.     |                                                                         |
  143.     |  Yale University Press   First Federal           Novell                 |
  144.     |                                                                         |
  145.     |  Ziff-Davis              Georgia Gulf            Pacific Gas & Electric |
  146.     |                                                                         |
  147.     |                                                                         |
  148.     +-------------------------------------------------------------------------+
  149.  
  150.     
  151.     +-------------------------------------------------------------------------+
  152.     |                                                                         |
  153.     |                                                                         |
  154.     |       The above list includes our best known customers, but omits       |
  155.     |       city, state or provincial government offices and hospitals.       |
  156.     |                                                                         |
  157.     |                                                                         |
  158.     +-------------------------------------------------------------------------+
  159.  
  160.  
  161.     ============================================================================
  162.                                  TABLE OF CONTENTS
  163.     ============================================================================
  164.  
  165.     INTRODUCTION  1
  166.        What is Parse-O-Matic?  1
  167.        Parse-O-Matic Versus Automatic Converters  1
  168.        Why You Need Parse-O-Matic -- An Example  2
  169.        Parse-O-Matic to the Rescue!  2
  170.        How It Works  3
  171.        How To Contact Us  3
  172.  
  173.     FUNDAMENTALS  4
  174.        The Parse-O-Matic Command  4
  175.        The POM File  4
  176.        Padding for Clarity  5
  177.        A Simple Example  6
  178.  
  179.     QUICK REFERENCE  7
  180.        Command Descriptions  7
  181.           Basic Commands  7
  182.           Output Commands  7
  183.           Input Commands  7
  184.           Input Filters  7
  185.           Flow Control Commands  8
  186.           Variable Modifiers  8
  187.           Free-Form Commands  8
  188.           Positional Commands  8
  189.           Date Commands  8
  190.           Calculation Commands  9
  191.           Input Preprocessors  9
  192.           Lookup Commands  9
  193.           Data Converters  9
  194.           Miscellaneous Commands  9
  195.        Command Formats  10
  196.  
  197.     BASIC COMMANDS  12
  198.        The SET Command  12
  199.           Basic Usage  12
  200.           The Trimming String  13
  201.           Non-Keyable Characters  14
  202.           The Null-Handling String  14
  203.        The IF Command  15
  204.  
  205.     OUTPUT COMMANDS  16
  206.        The KEEP Command  16
  207.        The OFILE Command  17
  208.           Basic Usage  17
  209.           Closing the Output File  18
  210.           Strong Deduction  18
  211.           Weak Deduction  19
  212.           Appended Deductions  20
  213.        The OUT and OUTEND Commands  20
  214.           Generating a Blank Line  21
  215.           Missing Output  21
  216.        The OUTHDG Command  22
  217.        The OUTPAGE Command  23
  218.        The PAGELEN Command  24
  219.  
  220.     INPUT COMMANDS  25
  221.        The GET Command  25
  222.           Variable Length Records  26
  223.           Delimiter-Terminated Data  28
  224.           Handling Long Delimiter-Terminated Data  29
  225.           Using GET with Text Files  29
  226.           End-of-File Considerations  30
  227.        The GETTEXT Command  31
  228.        The READNEXT Command  32
  229.           End of File Conditions  32
  230.           Optional Comparisons  32
  231.           Ignoring Null Lines  33
  232.           Saving the Previous Line  33
  233.        The REWIND Command  34
  234.           Why REWIND is Necessary  34
  235.           Using REWIND  34
  236.           Example  35
  237.  
  238.     INPUT FILTERS  36
  239.        The MINLEN Command  36
  240.        The IGNORE Command  37
  241.        The ACCEPT Command  37
  242.           Clustered Accepts  38
  243.  
  244.     FLOW CONTROL COMMANDS  39
  245.        The BEGIN Command  39
  246.        The CALL Command  41
  247.           Variable CALLs  41
  248.           Making Your Technique Obvious  41
  249.           Avoiding Unknown Code Sections  42
  250.        The CODE Command  43
  251.           Performance Considerations  44
  252.           Nested Subroutine Calls  44
  253.           Variable Code Sections  44
  254.           A Note to Experienced Programmers  45
  255.        The ELSE Command  45
  256.        The END Command  46
  257.        The AGAIN Command  47
  258.           Using AGAIN for Variable-Length Data  48
  259.           Pointless Command Combinations  49
  260.           Examples  49
  261.        The DONE Command  50
  262.        The NEXTFILE Command  52
  263.        The HALT Command  53
  264.        The PROLOGUE Command  54
  265.        The EPILOGUE Command  55
  266.  
  267.     VARIABLE MODIFIERS  56
  268.        The TRIM Command  56
  269.        The PAD Command  57
  270.        The CHANGE Command  58
  271.        The CVTCASE Command  58
  272.           Control Settings  59
  273.        The PROPER Command  60
  274.        The INSERT Command  62
  275.        The APPEND Command  63
  276.        The OVERLAY Command  64
  277.           Simple Arrays  65
  278.        The MAPFILE Command  66
  279.           What is a Map File?  66
  280.           Sample Map Files  66
  281.           Map File Format  67
  282.           Search Order  67
  283.           Case Matching  68
  284.           Reverse Mapping  68
  285.           Irreversible Mapping  69
  286.           Memory Limitations  70
  287.           An Example of Remapping  70
  288.        The REMAP Command  71
  289.           REMAP Versus CHANGE  71
  290.           Using REMAP  72
  291.  
  292.     FREE-FORM COMMANDS  73
  293.        What are Free-Form Commands?  73
  294.        The PARSE Command  74
  295.           Decapsulators  74
  296.           Sample Application  75
  297.           The Occurrence Number  75
  298.           Finding the Last Occurrence  76
  299.           Unsuccessful Searches  76
  300.           The Control Setting  77
  301.           The Plain Decapsulator  77
  302.           The Null Decapsulator  77
  303.           Null Decapsulators Versus Exclusion  78
  304.           Overlapping Decapsulators  78
  305.           Parsing Empty Fields  79
  306.           Additional Examples  79
  307.        The PEEL Command  80
  308.           The Control Setting  81
  309.           Parsing Empty Fields  81
  310.           The Left-Peeling Technique  82
  311.           The Leftover Technique  82
  312.  
  313.     POSITIONAL COMMANDS  84
  314.        General Discussion  84
  315.           What are Positional Commands?  84
  316.           Why Use Positional Commands?  84
  317.           A Cautionary Note  85
  318.        The SETLEN Command  86
  319.        The DELETE Command  87
  320.        The COPY Command  88
  321.        The EXTRACT Command  89
  322.        The FINDPOSN Command  90
  323.           The Plain String Find  90
  324.           Using a Single Decapsulator  91
  325.           The Encapsulated String Find  91
  326.           Control Settings  93
  327.           Insoluble Searches  94
  328.           Null Decapsulators  94
  329.           Finding The Last Word  95
  330.           Who Needs This?  95
  331.        The SCANPOSN Command  95
  332.           The Scanlist  96
  333.           Accommodating Variation  97
  334.           Handling Prefixes and Suffixes  97
  335.           Controlling the Search  98
  336.           Leftmost, Rightmost, Find-Any  98
  337.           The Best Match Principle  99
  338.  
  339.     DATE COMMANDS  101
  340.        General Discussion  101
  341.           The POMDATE.CFG File  101
  342.           Date Formats  101
  343.        The TODAY Command  103
  344.        The DATE Command  104
  345.        The MONTHNUM Command  105
  346.        The ZERODATE Command  106
  347.  
  348.     CALCULATION COMMANDS  107
  349.        The CALC Command  107
  350.        The CALCREAL Command  108
  351.        The ROUNDING Command  110
  352.        The CALCBITS Command  111
  353.  
  354.     INPUT PREPROCESSORS  113
  355.        The SPLIT Command  113
  356.           Indicating Actual Input Length  114
  357.           Non-Contiguous Splits  114
  358.        The CHOP Command  114
  359.           Manual Reading  115
  360.  
  361.     LOOKUP COMMANDS  116
  362.        The LOOKUP Command  116
  363.           Search Method  117
  364.           Limitations  117
  365.           Null Lines and Comments  118
  366.           Multiple Columns  118
  367.           LOOKUP Versus REMAP  119
  368.        The LOOKFILE Command  119
  369.        The LOOKCOLS Command  120
  370.        The LOOKSPEC Command  121
  371.  
  372.     DATA CONVERTERS  122
  373.        The MAKEDATA Command  122
  374.           Creating Binary Data  122
  375.           Converting Dates  123
  376.           Practical Considerations  124
  377.        The MAKETEXT Command  124
  378.           Converting Binary Data  125
  379.           Converting Dates  125
  380.           Practical Considerations  125
  381.  
  382.     MISCELLANEOUS COMMANDS  126
  383.        The ERASE Command  126
  384.        The FILESIZE Command  127
  385.        The GETENV Command  127
  386.           Disappearing Environment Variables  128
  387.           Examples  128
  388.        The LOG Command  129
  389.        The MSGWAIT Command  130
  390.           Standard Behavior  130
  391.           Setting a Time-Out Delay  131
  392.           Color Cues  131
  393.           Key Stacking  131
  394.           Exceptions  131
  395.           A Word of Caution  132
  396.        The PAUSE Command  132
  397.        The RANDOM Command  133
  398.        The SHOWNOTE Command  134
  399.           Other Notes  135
  400.           Slowing Down  135
  401.        The SOUND Command  136
  402.           The LISTEN Utility  136
  403.           Changing the Error Message Sound  137
  404.        The TRACE Command  137
  405.  
  406.     TERMS  138
  407.        Values  138
  408.        Variables  138
  409.        Predefined Values  139
  410.           $FLINE  139
  411.           $FLUPC  139
  412.           $SPLIT  140
  413.           $LINECOUNTER  140
  414.        Running Out of Variables, Literals or Lines  142
  415.        Delimiters  142
  416.        Illegal Characters  142
  417.        Using Comparators  143
  418.           Literal Comparisons and Sort Order  144
  419.           Numeric Comparisons  144
  420.           Upgrading from Earlier Versions  145
  421.        Predefined Data Types  146
  422.           Interpreting Data Formats in a File  147
  423.  
  424.     DEDUCED VARIABLES  148
  425.        Deduced Variables  148
  426.           Definition  148
  427.           The Look-Up Process  149
  428.           Restrictions  149
  429.           Usage Guidelines  150
  430.        Array Variables  151
  431.           Multidimensional Arrays  152
  432.        Eponymous Variables  153
  433.           Drawbacks and Advantages  154
  434.  
  435.     VALUE TECHNIQUES  155
  436.        Uninitialized and Persistent Variables  155
  437.           Example  155
  438.        Inline Incrementing and Decrementing  156
  439.        Line Counters  157
  440.        The SHOWNUM Utility  157
  441.           Quick Reference Screen  157
  442.           Converting a Number  158
  443.           Converting a Character  158
  444.           Windows Considerations  159
  445.  
  446.     PROGRAMMING TECHNIQUES  160
  447.        Tracing  160
  448.        Logging  161
  449.  
  450.     COMMAND-LINE TECHNIQUES  162
  451.        Quiet Mode  162
  452.        User-Specified Command-Line Parameters  162
  453.        Summary  165
  454.  
  455.     FILE HANDLING  166
  456.        How Parse-O-Matic Searches for a File  166
  457.        How Parse-O-Matic Opens an Output File  167
  458.        Appending to an Output File  169
  459.        Sending Output to a Device  170
  460.           COM Ports  170
  461.        DbF Files  171
  462.        POM and Wildcards  172
  463.  
  464.     OPERATIONAL TECHNIQUES  174
  465.        Parse-O-Matic Job (POJ) Files  174
  466.           Simple Usage  174
  467.           Commenting a Job File  174
  468.           Prompting for File Names  175
  469.           Suggesting File Names  176
  470.           Optional Parameters  176
  471.           Examples  177
  472.        Encrypted (Scrambled) POM Files  177
  473.           The SCRAMBLE Utility  177
  474.           Why Scramble a POM File?  178
  475.           Support Considerations  178
  476.        Batch Files  179
  477.        Unattended Operation  183
  478.        Examples  185
  479.  
  480.     OPERATIONAL CONSIDERATIONS  186
  481.        Running Parse-O-Matic on 8088 and 8086 Machines  186
  482.        Running Parse-O-Matic from Another Program  186
  483.        Solving Memory Problems  187
  484.  
  485.     RUNNING UNDER WINDOWS  188
  486.        Compatibility  188
  487.        Setting Up for Windows 95  188
  488.           Setting Up an Association for the POM File  189
  489.           Setting Up an Association for a POJ (Job) File  190
  490.           Setting Up an Association for the BAT File (Optional)  191
  491.        Installing the ShowNum Utility  192
  492.        Long File Names in Win95  192
  493.  
  494.     LICENSING  193
  495.        Parse-O-Matic Licenses  193
  496.        The SEE Utility  194
  497.  
  498.  
  499.     
  500.     ============================================================================
  501.                                     INTRODUCTION
  502.     ============================================================================
  503.     
  504.                                ----------------------
  505.                                What is Parse-O-Matic?
  506.                                ----------------------
  507.     
  508.     Parse-O-Matic is a programmable file-parser.  Simple enough for even a non-
  509.     programmer to master, it can help out in countless ways.  If you have a
  510.     file you want to edit, manipulate, or change around, Parse-O-Matic may be
  511.     just the tool you need.  Parse-O-Matic can also speed up or automate long
  512.     or repetitive editing tasks.
  513.     
  514.                      -----------------------------------------
  515.                      Parse-O-Matic Versus Automatic Converters
  516.                      -----------------------------------------
  517.     
  518.     Parse-O-Matic is not an "automatic file converter".  It will not, for
  519.     example, convert WordPerfect files to MS-Word format, or convert Lotus
  520.     1-2-3 Spreadsheets DIRECTLY to Excel files -- although it can read reports
  521.     from one program and convert them to another format (e.g. comma-delimited),
  522.     which can be imported by the other program.
  523.     
  524.     One advantage of this method (as opposed to automatic file conversion) is
  525.     that you can create an "intelligent" importing procedure, which can make
  526.     decisions and modify data.  You could, for example, eliminate certain types
  527.     of records, tidy up names, convert case, unify fields, make calculations,
  528.     and so on.
  529.     
  530.  
  531.  
  532.  
  533.  
  534.  
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545.  
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.                                                                               1
  554.                       ----------------------------------------
  555.                       Why You Need Parse-O-Matic -- An Example
  556.                       ----------------------------------------
  557.     
  558.     There are plenty of programs out there that have valuable data locked away
  559.     inside them.  How do you get that data OUT of one program and into another
  560.     one?
  561.     
  562.     Some programs provide a feature which "exports" a file into some kind of
  563.     generic format.  Perhaps the most popular of these formats is known as a
  564.     "comma-delimited file", which is a text file in which each data field is
  565.     separated by a comma.  Character strings -- which might themselves contain
  566.     commas -- are surrounded by double quotes.  So a few lines from a
  567.     comma-delimited file might look something like this (an export from a
  568.     hypothetical database of people who owe your company money):
  569.     
  570.     "JONES","FRED","1234 GREEN AVENUE", "KANSAS CITY", "MO",293.64
  571.     "SMITH","JOHN","2343 OAK STREET","NEW YORK","NY",22.50
  572.     "WILLIAMS","JOSEPH","23 GARDEN CRESCENT","TORONTO","ON",16.99
  573.     
  574.     Unfortunately, not all programs export or import data in this format.
  575.     Even more frustrating is a program that exports data in a format that is
  576.     ALMOST what you need!
  577.     
  578.     If that's the case, you might decide to spend a few hours in a text editor,
  579.     modifying the export file so that the other program can understand it.  Or
  580.     you might write a program to do the editing for you.  Both solutions are
  581.     time-consuming.
  582.     
  583.     An even more challenging problem arises when a program which has no export
  584.     capability does have the ability to "print" reports to a file.  You can
  585.     write a program to read these files and convert them to something you can
  586.     use, but this can be a LOT of work!
  587.     
  588.                             ----------------------------
  589.                             Parse-O-Matic to the Rescue!
  590.                             ----------------------------
  591.     
  592.     Parse-O-Matic is a utility that reads a file, interprets the data, and
  593.     outputs the result to another file.  It can help you "boil down" data to
  594.     its essential information.  You can also use it to convert NEARLY
  595.     compatible import files, or generate printable reports.
  596.     
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.                                                                               2
  609.                                     ------------
  610.                                     How It Works
  611.                                     ------------
  612.     
  613.     You need three things:
  614.     
  615.     1) The Parse-O-Matic program
  616.     2) A Parse-O-Matic "POM" file (to tell Parse-O-Matic what to do)
  617.     3) The input file
  618.     
  619.     The input file might be a report or data file from another program, or text
  620.     captured from a communications session.  Parse-O-Matic can handle many
  621.     types of input.  We've provided several sample input files. For example,
  622.     the file XMPDAT02.TXT comes from the AccPac accounting software.  AccPac is
  623.     a great program, but its export capabilities leave something to be desired.
  624.     Parse-O-Matic can help!
  625.     
  626.     To see detailed demonstrations of how various files can be parsed, enter
  627.     START at the DOS prompt (or run START.BAT from Windows or OS/2), then
  628.     select TUTORIAL from the menu.
  629.     
  630.                                  -----------------
  631.                                  How To Contact Us
  632.                                  -----------------
  633.     
  634.     If you have any questions about Parse-O-Matic, you can write to us at the
  635.     following address:
  636.     
  637.              Pinnacle Software, CP386, Mount Royal, QC, Canada H3P 3C6
  638.     
  639.     You can also contact us electronically at the following addresses:
  640.     
  641.                         Voice Line: 514-345-9578
  642.                     Internet Email: psoftinfo@aol.com
  643.                     World Wide Web: http://users.aol.com/psoftinfo
  644.                         CompuServe: psoftinfo
  645.     
  646.     
  647.     
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.                                                                               3
  664.     ============================================================================
  665.                                     FUNDAMENTALS
  666.     ============================================================================
  667.     
  668.     
  669.     This documentation assumes that you are an experienced computer user.  If
  670.     you have trouble, you might ask a programmer to help you -- POM file
  671.     creation is a little like programming!
  672.     
  673.                              -------------------------
  674.                              The Parse-O-Matic Command
  675.                              -------------------------
  676.     
  677.     The basic format of the Parse-O-Matic command line is:
  678.     
  679.     POM pom-file input-file output-file
  680.     
  681.     Here is an example, as you would type it at the DOS command line, or as a
  682.     command in a batch file:  POM POMFILE.POM REPORT.TXT OUTPUT.TXT
  683.     
  684.     For a more formal description of the command line, start up POM by typing
  685.     this command at the DOS prompt:  POM
  686.     
  687.     Another method of calling the POM command is to specify a job (.POJ) file.
  688.     This is explained later, in the "Operational Planning" chapter -- see
  689.     "Parse-O-Matic Job (POJ) Files".  Briefly, a job file lets you save the
  690.     Parse-O-Matic command-line specifications in a text file.
  691.     
  692.                                     ------------
  693.                                     The POM File
  694.                                     ------------
  695.     
  696.     The POM file is a text file with a .POM extension.  The following
  697.     conventions are used when interpreting the POM file:
  698.     
  699.     - Null lines and lines starting with a semi-colon (comments) are ignored.
  700.     
  701.     - A POM file may contain up to 750 lines of specifications.
  702.       Comment lines do not count in this total.
  703.     
  704.     A POM file does not rely on "loops" (to use the programming term).  Each
  705.     line or record of the input file is processed by the entire POM file.  If
  706.     you would like this expressed in terms of programming languages, here is
  707.     what POM does:
  708.     
  709.     +-------------------------------------------------------------------------+
  710.     |      START: If there's nothing left in the input file, go to QUIT.      |
  711.     |             Read a line from the input file                             |
  712.     |             Do everything in the POM file                               |
  713.     |             Go to START                                                 |
  714.     |      QUIT:  Tell the user you are finished!                             |
  715.     +-------------------------------------------------------------------------+
  716.     
  717.  
  718.                                                                               4
  719.     The method by which Parse-O-Matic finds the POM file is discussed in the
  720.     section "How Parse-O-Matic Searches for a File".
  721.     
  722.                                 -------------------
  723.                                 Padding for Clarity
  724.                                 -------------------
  725.     
  726.     Spaces and tabs between the words and variables in a POM file line are
  727.     generally ignored (except in the case of the "output picture" of the OUT
  728.     and OUTEND commands).  You can use spaces to make the commands in your POM
  729.     files easier to read.
  730.     
  731.     Additionally, in any line in the POM file, the following terms are ignored:
  732.     
  733.     THEN   ELSE
  734.     
  735.     (There is a POM command named ELSE, but Parse-O-Matic can tell that this is
  736.     not "padding".)
  737.     
  738.     Finally, the equals ("=") character is ignored if it is found in a place
  739.     where no comparison is taking place.  This will be demonstrated below.
  740.     
  741.     You can use these techniques to make your POM files easier to read.  For
  742.     example, the IF command can be written in several ways:
  743.     
  744.     Very terse:          IF PRICE = "0.00" BONUS "0.00" "1.00"
  745.     
  746.     Padded with spaces:  IF PRICE = "0.00"   BONUS   "0.00"   "1.00"
  747.     
  748.     Fully padded:        IF PRICE = "0.00" THEN BONUS = "0.00" ELSE "1.00"
  749.     
  750.     In the last example, the first equals sign ("=") is a "comparator".  (For
  751.     details about comparators, see the section entitled "Using Comparators".)
  752.     The second equals sign is not really required, but it does make the line
  753.     easier to understand.
  754.     
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.                                                                               5
  774.                                   ----------------
  775.                                   A Simple Example
  776.                                   ----------------
  777.     
  778.     Let's say you have a text file called NAMES.TXT that looks like this:
  779.     
  780.     WILLIAMS   JACK
  781.     SMITH      JOHNNY
  782.     JOHNSON    MARY
  783.     :          :
  784.     Column 1   Column 12
  785.     
  786.     Now let's say you want to switch the columns, so that the first name
  787.     appears first.  Your first step is to create a file using a text editor.
  788.     The file would look like this:
  789.     
  790.     SET    last  = $FLINE[ 1 10]
  791.     SET    first = $FLINE[12 17]
  792.     PAD    first "R" " " "10"
  793.     OUTEND |{first} {last}
  794.     
  795.     The first two lines tell Parse-O-Matic which text to extract from each
  796.     input line.  For the first line of the input file, the variable named
  797.     'last' will be given the value "WILLIAMS  ".  You will notice there are two
  798.     spaces at the end.  That is because we take every character from position 1
  799.     to position 10 -- which in this case includes two spaces.
  800.     
  801.     The PAD line adds enough spaces on the right side of the variable named
  802.     'first' to make sure that it is 10 characters long.  The OUTEND command
  803.     sends the two variables to the output file.
  804.     
  805.     Save the file with the name TEST.POM and exit your text editor.  At the DOS
  806.     prompt, enter this command:
  807.     
  808.     POM TEST.POM NAMES.TXT OUTPUT.TXT
  809.     
  810.     This will run the POM file (TEST.POM) on every line of the input file
  811.     (NAMES.TXT) and place the output in the file OUTPUT.TXT, which will then
  812.     look like this:
  813.     
  814.     JACK       WILLIAMS
  815.     JOHNNY     SMITH
  816.     MARY       JOHNSON
  817.     :          :
  818.     Column 1   Column 12
  819.     
  820.     Of course, for such a simple task, it would be easier to switch the columns
  821.     yourself, using a text editor.  But when you are dealing with large amounts
  822.     of data, and want to guard against typing errors, Parse-O-Matic can save
  823.     you a lot of time, effort and risk.  It also lets you automate editing
  824.     operations that you perform frequently.
  825.     
  826.  
  827.  
  828.                                                                               6
  829.     ============================================================================
  830.                                   QUICK REFERENCE
  831.     ============================================================================
  832.     
  833.                                 --------------------
  834.                                 Command Descriptions
  835.                                 --------------------
  836.     
  837.     This manual's explanations of the commands are grouped by related functions,
  838.     in the following order:
  839.     
  840.     ---------------------------------------------------------------------------
  841.     Basic Commands
  842.     ---------------------------------------------------------------------------
  843.     SET       Assigns a value to a variable
  844.     IF        Conditionally assigns a value to a variable
  845.     
  846.     ---------------------------------------------------------------------------
  847.     Output Commands
  848.     ---------------------------------------------------------------------------
  849.     KEEP      Do a page eject if less than the specified number of lines remain
  850.     OFILE     Specify output file or device
  851.     OUT       Sends text and variables to the output file
  852.     OUTEND    Like OUT but adds a new line at end (Carriage Return/Linefeed)
  853.     OUTHDG    Sets up title lines to appear at the top of a report or each page
  854.     OUTPAGE   Starts a new page
  855.     PAGELEN   Sets the page length for a report
  856.     
  857.     ---------------------------------------------------------------------------
  858.     Input Commands
  859.     ---------------------------------------------------------------------------
  860.     GET       Manually reads bytes from the input file
  861.     GETTEXT   Manually reads bytes from the input file, converts them to text
  862.     READNEXT  Moves to next input line but retains your place in the POM file
  863.     REWIND    Backs up a specified number of bytes in an input file
  864.     
  865.     ---------------------------------------------------------------------------
  866.     Input Filters
  867.     ---------------------------------------------------------------------------
  868.     MINLEN    Sets minimum length required for an input line to be processed
  869.     IGNORE    Ignores an input line that meets the specified condition
  870.     ACCEPT    Accepts an input line that meets the specified condition
  871.     
  872.  
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.                                                                               7
  884.     ---------------------------------------------------------------------------
  885.     Flow Control Commands
  886.     ---------------------------------------------------------------------------
  887.     BEGIN     Defines the conditions for processing the code block
  888.     CALL      Calls a subroutine code block
  889.     CODE      Marks the start of a subroutine code block
  890.     ELSE      Defines the start of code to be processed if the BEGIN fails
  891.     END       Ends a code block (BEGIN/END, CODE/END, PROLOGUE/END etc.)
  892.     AGAIN     Conditionally returns to the corresponding BEGIN command
  893.     DONE      Reads the next input line and starts at the top of the POM file
  894.     NEXTFILE  Skips the current input file and proceeds to the next (if any)
  895.     HALT      Terminates all processing if a given condition exists
  896.     PROLOGUE  Defines code block to run before any input lines are processed
  897.     EPILOGUE  Defines code block to run after  all input lines are processed
  898.     
  899.     ---------------------------------------------------------------------------
  900.     Variable Modifiers
  901.     ---------------------------------------------------------------------------
  902.     TRIM      Removes a character from the left, right or all of a variable
  903.     PAD       Centers, or left/right-justifies variable to a specified width
  904.     CHANGE    Replaces all occurrences of a string in a variable
  905.     PROPER    Properizes a variable (e.g. "JOHN SMITH" becomes "John Smith")
  906.     INSERT    Inserts a string on the left or right, or at a "found" position
  907.     APPEND    Concatenates several variables into one variable
  908.     OVERLAY   Extends or overwrites portions of a variable
  909.     CVTCASE   Converts a value to uppercase or lowercase
  910.     MAPFILE   Reads a file containing data transformations for REMAP
  911.     REMAP     Transforms sub-strings into other strings
  912.     
  913.     ---------------------------------------------------------------------------
  914.     Free-Form Commands
  915.     ---------------------------------------------------------------------------
  916.     PARSE     Obtains a variable found between delimiters in free-form data
  917.     PEEL      Works like PARSE, but removes the "found" text from the data
  918.     
  919.     ---------------------------------------------------------------------------
  920.     Positional Commands
  921.     ---------------------------------------------------------------------------
  922.     SETLEN    Sets a variable according to the length of a value
  923.     DELETE    Removes a range of characters from a variable
  924.     COPY      Copies a range of characters from a value to a variable
  925.     EXTRACT   Like COPY, but removes the characters from the source variable
  926.     FINDPOSN  Finds the starting or ending position of a value in another
  927.     SCANPOSN  Finds "best match" in list of values, returns start/end positions
  928.     
  929.     ---------------------------------------------------------------------------
  930.     Date Commands
  931.     ---------------------------------------------------------------------------
  932.     TODAY     Sets a variable to today's date, in a variety of formats
  933.     DATE      Sets a given year, month and day, in a variety of formats
  934.     MONTHNUM  Sets the month number of a given month, expressed as text
  935.     
  936.  
  937.  
  938.                                                                               8
  939.     ---------------------------------------------------------------------------
  940.     Calculation Commands
  941.     ---------------------------------------------------------------------------
  942.     CALC      Performs arithmetic functions on integer values
  943.     CALCREAL  Performs arithmetic functions on decimal values
  944.     ROUNDING  Controls rounding in CALCREAL operations
  945.     
  946.     ---------------------------------------------------------------------------
  947.     Input Preprocessors
  948.     ---------------------------------------------------------------------------
  949.     SPLIT     Breaks up a wide text file (more than 255 characters)
  950.     CHOP      Breaks up a fixed-record-length file
  951.     
  952.     ---------------------------------------------------------------------------
  953.     Lookup Commands
  954.     ---------------------------------------------------------------------------
  955.     LOOKUP    Looks up a word in another file and returns a corresponding value
  956.     LOOKFILE  Specifies the file that the LOOKUP command will use (see also /L)
  957.     LOOKCOLS  Specifies the format of the look-up file
  958.     LOOKSPEC  Controls the behavior of the LOOKUP command
  959.     
  960.     ---------------------------------------------------------------------------
  961.     Data Converters
  962.     ---------------------------------------------------------------------------
  963.     MAKEDATA  Converts text into binary format
  964.     MAKETEXT  Converts binary format into text
  965.     
  966.     ---------------------------------------------------------------------------
  967.     Miscellaneous Commands
  968.     ---------------------------------------------------------------------------
  969.     ERASE     Deletes a file
  970.     FILESIZE  Obtains the size of a file (in bytes)
  971.     GETENV    Obtains a system environment variable (e.g. PATH)
  972.     LOG       Adds a line to the processing log
  973.     MSGWAIT   Controls the behavior of error messages
  974.     PAUSE     Delays the specified number of milliseconds
  975.     RANDOM    Generates a random number
  976.     SHOWNOTE  Displays a message on the processing screen
  977.     SOUND     Makes a noise or sets the noise generated by error messages
  978.     TRACE     Traces a variable (results saved in the text file POM.TRC)
  979.     
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.                                                                               9
  994.                                   ---------------
  995.                                   Command Formats
  996.                                   ---------------
  997.     
  998.     ----------------------------------  ---------------------------------------
  999.     COMMAND FORMATS                     EXAMPLE
  1000.     ----------------------------------  ---------------------------------------
  1001.     ACCEPT   val c val                  ACCEPT   $FLINE[1 3] = "YES"
  1002.     AGAIN    [val c val]                AGAIN    linecntr #< "3"
  1003.     APPEND   var val val [val [val]]    APPEND   name first last
  1004.     BEGIN    [val c val]                BEGIN    linecntr #< "3"
  1005.     CALL     val                        CALL     "Format Price Field"
  1006.     CALC     var num operation num      CALC     total total "+" sold
  1007.     CALCBITS var char operation char    CALCBITS z byte1 "XOR" $80
  1008.     CALCREAL var num operation num      CALCREAL salary hours "*" rate
  1009.     CHANGE   var val val                CHANGE   date "/" "-"
  1010.     CHOP     from to [,from to] [...]   CHOP     1 250, 251 300
  1011.     CODE     val                        CODE     "Format Price Field"
  1012.     COPY     var val from [to]          COPY     x $FLINE "3" "5"
  1013.     CVTCASE  var val [ctl]              CVTCASE  x $FLINE "L7"
  1014.     DATE     var num num num [ctl]      DATE     x "98" "12" "31"
  1015.     DELETE   var from [to]              DELETE   x "3" "5"
  1016.     DONE     [val c val]                DONE     $FLINE = "End Data"
  1017.     ELSE                                ELSE
  1018.     END                                 END
  1019.     EPILOGUE                            EPILOGUE
  1020.     ERASE    file                       ERASE    "C:\MYFILES\OUTPUT.TXT"
  1021.     EXTRACT  var var from [to]          EXTRACT  x $FLINE "15" "30"
  1022.     FILESIZE var file                   FILESIZE x "C:\MYFILES\INPUT.TXT"
  1023.     FINDPOSN var val left [right [ctl]] FINDPOSN x $FLINE "2*/"
  1024.     GET      var ctl [ctl [ctl]]        GET      x #0 "END" "I"
  1025.     GETENV   var val                    GETENV   x "COMSPEC"
  1026.     GETTEXT  var ctl [ctl]              GETTEXT  date "WORD" "DATE"
  1027.     HALT     val c val val [ctl]        HALT     x = y "Item repeated"
  1028.     IF       val c val var val [val]    IF       x = "Y" THEN z = "N"
  1029.     IGNORE   val c val                  IGNORE   price = "0.00"
  1030.     INSERT   var ctl val                INSERT   price "L" "$"
  1031.     KEEP     num                        KEEP     "5"
  1032.     LOG      val c val val [val [val]]  LOG      x = y "Item repeated"
  1033.     LOOKCOLS num num num num            LOOKCOLS "1" "3" "8" "255"
  1034.     LOOKFILE file                       LOOKFILE "C:\TABLES\DATA.TBL"
  1035.     LOOKSPEC ctl ctl ctl                LOOKSPEC "Y" "N" "N"
  1036.     LOOKUP   var val                    LOOKUP   phonenum "FRED JONES"
  1037.     MAKEDATA var val ctl                MAKEDATA x "255" "BYTE"
  1038.     MAKETEXT var val ctl                MAKETEXT z x "BYTE"
  1039.     MAPFILE  file val [ctl]             MAPFILE  "XYZ.MPF" "XYZ" "ANYCASE"
  1040.     MINLEN   num [num]                  MINLEN   "15" "1"
  1041.     MONTHNUM var val                    MONTHNUM x "February"
  1042.     MSGWAIT  num                        MSGWAIT  "60"
  1043.     NEXTFILE [val c val]                NEXTFILE $FLINE = "End File"
  1044.     OFILE    file [val [ctl]]           OFILE    "C:\MYFILES\OUT.TXT"
  1045.     OUT      [val c val] |pic           OUT      z = "X" |{price}
  1046.     OUTEND   [val c val] |pic           OUTEND   z = "X" |{$FLINE}
  1047.  
  1048.                                                                              10
  1049.     OUTHDG   val                        OUTHDG   "LIST OF EMPLOYEES"
  1050.     OUTPAGE  [val c val]                OUTPAGE  partnum <> oldpartnum
  1051.     OVERLAY  var val from               OVERLAY  x "***" "15"
  1052.     PAD      var ctl char num           PAD      sernum "L" "0" "10"
  1053.     PAGELEN  num [ctl]                  PAGELEN  "66" "N"
  1054.     PARSE    var val left right [ctl]   PARSE    x $FLINE "2*(" "3*)" "I"
  1055.     PAUSE    num                        PAUSE    "1000"
  1056.     PEEL     var var left right [ctl]   PEEL     x $FLINE "2*(" "3*)" "I"
  1057.     PROLOGUE                            PROLOGUE
  1058.     PROPER   var [ctl [file]]           PROPER   custname "I" "XY.PEF"
  1059.     RANDOM   var val val                RANDOM   roll "1" "6"
  1060.     READNEXT [val c val]                READNEXT $FLINE[1 5] = "NOTE:"
  1061.     REMAP    var [val]                  REMAP    $FLINE "BIN2CODE"
  1062.     REWIND   [num]                      REWIND   "15"
  1063.     ROUNDING val                        ROUNDING "N"
  1064.     SCANPOSN var var val val [ctl]      SCANPOSN from to $FLINE "/MR/MISS/MRS"
  1065.     SET      var val [val [val]]        SET      price $FLINE[20 26] "L$" "0"
  1066.     SETLEN   var val                    SETLEN   length custname
  1067.     SHOWNOTE val [val] [val] [...]      SHOWNOTE "Processing record #" recnum
  1068.     SOUND    ctl                        SOUND    "BUZZ"
  1069.     SPLIT    from to [,from to] [...]   SPLIT    1 250, 251 300
  1070.     TODAY    var [ctl]                  TODAY    x "?y/?n/?d"
  1071.     TRACE    var                        TRACE    price
  1072.     TRIM     var ctl char               TRIM     price "R" "$"
  1073.     ZERODATE num num num                ZERODATE "1753" "12" "31"
  1074.     ----------------------------------  ---------------------------------------
  1075.     
  1076.     The following conventions are used in the preceding table:
  1077.     
  1078.     c      Comparator (if omitted, defaults to "equals" comparison)
  1079.     char   Variable or literal: must be a single byte or character
  1080.     ctl    Variable or literal: command control specifications
  1081.     file   File name (see "How Parse-O-Matic Searches for a File")
  1082.     from   Variable or literal: a starting character position (see Note #1)
  1083.     left   Variable or literal: see "Decapsulators"
  1084.     num    Variable or literal: must contain a number (see Note #1)
  1085.     pic    Output picture used by OUT and OUTEND
  1086.     right  Variable or literal: see "Decapsulators"
  1087.     to     Variable or literal: an ending position (see Note #1)
  1088.     val    Variable or literal whose value is being read
  1089.     var    Variable that is being set
  1090.     [xxx]  Square brackets indicate optional items
  1091.     
  1092.     Note #1:  Tabs, spaces and commas are stripped from numeric values
  1093.     
  1094.     The commands are explained in detail in the following section.  A summary
  1095.     of the commands and default settings appear, as comments, in the file
  1096.     QUICKREF.POM.  You can copy these comments into your own POM file as
  1097.     a convenient quick reference.
  1098.     
  1099.     
  1100.     
  1101.  
  1102.  
  1103.                                                                              11
  1104.     ============================================================================
  1105.                                    BASIC COMMANDS
  1106.     ============================================================================
  1107.     
  1108.                                   ---------------
  1109.                                   The SET Command
  1110.                                   ---------------
  1111.     
  1112.     FORMAT:        SET var1 value1 [value2 [value3]]
  1113.     
  1114.     PURPOSE:       SET assigns value1 to the variable var1.
  1115.     
  1116.     PARAMETERS:    var1   is the variable being set
  1117.                    value1 is the value being read
  1118.                    value2 is the optional trimming string
  1119.                    value3 is the optional null-handling string
  1120.     
  1121.     ALTERNATIVES:  The COPY command, or just about any command that sets
  1122.                    a variable.
  1123.     
  1124.     SEE ALSO:      The TRIM Command
  1125.     
  1126.     -----------
  1127.     Basic Usage
  1128.     -----------
  1129.     
  1130.     The usual reason to use the SET command is to set a variable from the input
  1131.     line (represented by the variable $FLINE) prior to cleaning it up with TRIM.
  1132.     
  1133.     For example, if the input line looked like this:
  1134.     
  1135.     JOHN       SMITH     555-1234   322 Westchester Lane    Architect
  1136.     |          |         |          |                       |
  1137.     Column 1   Col 12    Col 22     Col 33                  Col 57
  1138.     
  1139.     then we could extract the last name from the input line with these two POM
  1140.     commands:
  1141.     
  1142.     SET  name1 = $FLINE[12 21]   <-- Sets the variable name1 from the input line
  1143.     TRIM name1  "R"  " "         <-- Trims any spaces on the right side
  1144.     
  1145.     SET would first assign the variable name1 this value:     "SMITH     "
  1146.     After the TRIM, the variable name1 would have the value:  "SMITH"
  1147.     
  1148.     You will also use SET if you plan to include a portion of text string in
  1149.     the output, since the OUT and OUTEND commands do not recognize substrings
  1150.     (e.g. myvar[10 20]) after the "|" marker; they only recognize plain text
  1151.     and complete variables.
  1152.     
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.                                                                              12
  1159.     -------------------
  1160.     The Trimming String
  1161.     -------------------
  1162.     
  1163.     After SETting a variable, you may wish to use one or more TRIM commands to
  1164.     "tidy up" the variable by removing leading and trailing spaces, extraneous
  1165.     commas, and so on.  However, you can do this at the same time as you do the
  1166.     SET command, using the optional "trimming string".
  1167.     
  1168.     The trimming string is a list of pairs of characters.  The first character
  1169.     in the pair is the TRIM specification, while the second is the character
  1170.     being trimmed.
  1171.     
  1172.     Consider the following POM code:
  1173.     
  1174.     SET   xyz    = "xx$3.00xx"
  1175.     SET   price1 = xyz            <-- Sets price1 to "XX$3.00XX"
  1176.     TRIM  price1 "B" "x"          <-- Sets price1 to "$3.00"
  1177.     TRIM  price1 "L" "$"          <-- Sets price1 to "3.00"
  1178.     
  1179.     This achieves the desired result (i.e. it gets rid of the "x" characters and
  1180.     the dollar sign), but it takes up four lines of code.  You can use SET's
  1181.     trimming string to accomplish the same thing:
  1182.     
  1183.     SET   xyz    = "xx$3.00xx"
  1184.     SET   price1 = xyz "BxL$"     <-- Sets price1 to "3.00"
  1185.     
  1186.     The "BxL$" trimming string (made up of the character pairs "Bx" and "L$")
  1187.     instructs Parse-O-Matic as follows:
  1188.     
  1189.     CHAR  TRIMMING
  1190.     PAIR  OPERATION
  1191.     ----  ---------
  1192.      Bx   Strip away "x" on Both sides of the value, yielding "$3.00", then...
  1193.      L$   Strip the dollar sign on the Left side, yielding "3.00"
  1194.     
  1195.     The trimming string is interpreted from left to right.  Thus, the following
  1196.     commands would NOT produce the same result as the previous example:
  1197.     
  1198.     SET   xyz    = "xx$3.00xx"
  1199.     SET   price1 = xyz "L$Bx"
  1200.     
  1201.     Parse-O-Matic will try to strip the dollar signs on the left, but since
  1202.     there are none there, it will move on to the next step without changing
  1203.     anything.  It will then remove the "x" characters.  The final result will
  1204.     be "$3.00", not "3.00".
  1205.     
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.                                                                              13
  1214.     ----------------------
  1215.     Non-Keyable Characters
  1216.     ----------------------
  1217.     
  1218.     In the trimming string, the second character in each character-pair must be
  1219.     a keyable character (i.e. something you can type on your keyboard and see on
  1220.     your screen).  You can not use the $hex or #decimal representations (see
  1221.     "Values" in the "Terms" chapter).
  1222.     
  1223.     The following command is valid:
  1224.     
  1225.     SET   num1 = $FLINE[10 20] "B A,"
  1226.     
  1227.     This will remove the spaces on both sides and eliminate any commas.
  1228.     
  1229.     The following command is NOT valid:
  1230.     
  1231.     SET   hex1 = $FLINE[10 20] "B$00R#13"
  1232.     
  1233.     The SET command can not translate the $00 code into "hex character zero".
  1234.     Similarly, it does not recognize the #13 as "decimal character 13" (which
  1235.     is, by the way, the ASCII "carriage return" character).
  1236.     
  1237.     To strip non-keyable characters, use the TRIM command.
  1238.     
  1239.     ------------------------
  1240.     The Null-Handling String
  1241.     ------------------------
  1242.     
  1243.     Sometimes you want to assign a "default" value to a variable if it turns out
  1244.     to be null (i.e. empty).  Here is one way to do this:
  1245.     
  1246.     SET   xyz = ""                       <-- This is a null string
  1247.     SET   price1 = xyz                   <-- Sets price1 to ""
  1248.     IF    price1 = "" THEN price1 = "0"  <-- Sets price1 to "0"
  1249.     
  1250.     It is easier to do this by using the null-handling string, as in this
  1251.     example:
  1252.     
  1253.     SET   xyz    = "$3.00"               <-- This is a normal price
  1254.     SET   price1 = xyz "L$" "0.00"       <-- Sets price1 to "3.00"
  1255.     SET   xyz    = "$"                   <-- This is just a dollar sign!
  1256.     SET   price2 = xyz "L$" "0.00"       <-- Sets price2 to "0.00"
  1257.     
  1258.     In the first case (xyz = "$3.00"), all we had to do was strip away the
  1259.     dollar sign to obtain the price.  In the second case (xyz = "$"), we
  1260.     ended up with a null value after stripping away the dollar sign.  In such
  1261.     case, the null-handling string ("0.00") specified the default value.
  1262.     
  1263.  
  1264.  
  1265.  
  1266.  
  1267.  
  1268.                                                                              14
  1269.     Sometimes you don't want to do any triming, but you do want to check for a
  1270.     default value. Nevertheless, the trimming string must be included in the
  1271.     command, as a "place holder".  For example:
  1272.     
  1273.     SET   xyz    = "Fred Smith"          <-- This is a normal name
  1274.     SET   name1  = xyz "" "Unknown"      <-- Sets name1 to "Fred Smith"
  1275.     SET   xyz    = ""                    <-- This is a null string
  1276.     SET   name2  = xyz "" "Unknown"      <-- Sets name2 to "Unknown"
  1277.     
  1278.     As you can see, no trimming was necessary, but we nevertheless had to
  1279.     include the trimming string, even though it was null (meaning, "Don't
  1280.     do any trimming").
  1281.     
  1282.                                    --------------
  1283.                                    The IF Command
  1284.                                    --------------
  1285.     
  1286.     FORMAT:        IF value1 [comparator] value2 var1 value3 [value4]
  1287.     
  1288.     PURPOSE:       If value1 equals value2, var1 is set to value3.  Otherwise,
  1289.                    it is set to value4 (if value4 is missing, nothing is done,
  1290.                    and var1 is not changed).
  1291.     
  1292.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1293.                    In the following explanation, we will demonstrate the
  1294.                    command using only the "literally identical" ("=")
  1295.                    comparator.
  1296.     
  1297.     ALTERNATIVES:  The BEGIN command
  1298.     
  1299.     Here is an example of the IF command...
  1300.     
  1301.     SET  EARNING = $FLINE[20 23]
  1302.     IF   EARNING = "0.00" THEN BONUS = "0.00" ELSE "1.00"
  1303.     
  1304.     This obtains the value between columns 20 and 26, then checks if it equals
  1305.     "0.00".  If it does, the variable BONUS is set to 0.00.  If not, BONUS is
  1306.     set to "1.00".  The "THEN" and "ELSE" are "padding" and can be omitted.
  1307.     
  1308.     
  1309.     
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322.  
  1323.                                                                              15
  1324.     ============================================================================
  1325.                                   OUTPUT COMMANDS
  1326.     ============================================================================
  1327.     
  1328.                                   ----------------
  1329.                                   The KEEP Command
  1330.                                   ----------------
  1331.     
  1332.     FORMAT:        KEEP value1
  1333.     
  1334.     PURPOSE:       KEEP does a page eject if less than the specified number of
  1335.                    lines remain on the page.
  1336.     
  1337.     PARAMETERS:    value1 is the minimum number of lines required to avoid doing
  1338.                    a page eject.
  1339.     
  1340.     ALTERNATIVES:  The OUTPAGE command, used with $LINECOUNTER
  1341.     
  1342.     NOTES:         KEEP has no effect unless the page length is set, using the
  1343.                    PAGELEN command.
  1344.     
  1345.     SEE ALSO:      "The OutHdg Command"
  1346.     
  1347.     When you are sending output to a file that will be printed (or sending
  1348.     output directly to a printer -- see "How Parse-O-Matic Opens an Output
  1349.     File"), you sometimes want to ensure that certain lines of data are kept
  1350.     together on the same page.  The most common situation involves a heading
  1351.     that precedes some associated data; you do not want to have the heading by
  1352.     itself at the bottom of one page, with the data on the next. Consider this
  1353.     POM file:
  1354.     
  1355.     PAGELEN  "55"                        <-- Set the output page length
  1356.     SET      part     = $FLINE[ 1 10]    <-+
  1357.     SET      type     = $FLINE[12 20]      | Extract the fields
  1358.     SET      quantity = $FLINE[22 30]    <-+
  1359.     BEGIN    lasttype <> type            <-- Detect a change in part type
  1360.       SET      lasttype = part           <-- Remember this part type
  1361.       KEEP     "4"                       <-- Make sure we have 4 lines left
  1362.       OUTEND   |                         <-- Output a blank line
  1363.       OUTEND   |PART TYPE:  {type}       <-- Output a header
  1364.     END                                  <-- End of code block
  1365.     OUTEND   {part} {quantity}           <-- Output part data
  1366.     
  1367.     This POM file will always make sure that at least two part numbers follow
  1368.     the heading; a heading will never be "stranded" by itself at the end of a
  1369.     page.
  1370.     
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.                                                                              16
  1379.                                  -----------------
  1380.                                  The OFILE Command
  1381.                                  -----------------
  1382.     
  1383.     FORMAT:        OFILE value1
  1384.                    OFILE value1 [value2 [value3]]
  1385.     
  1386.     PURPOSE:       OFILE specifies a new output file or device.
  1387.     
  1388.     PARAMETERS:    value1 is the name of the output file or device
  1389.                    value1 can also be a subcommand (i.e. a command for OFILE)
  1390.                    value2 is the default extension for the DEDUCE subcommand
  1391.                    value3 is the control value for the DEDUCE subcommand
  1392.     
  1393.     DEFAULTS:      value2 defaults to "" for the DEDUCE subcommand
  1394.                    value3 defaults to "WEAK" for the DEDUCE subcommand
  1395.     
  1396.     ALTERNATIVES:  Specify the name of the output file on the POM command line
  1397.     
  1398.     SEE ALSO:      "How Parse-O-Matic Opens an Output File"
  1399.                    "Sending Output to a Device"
  1400.     
  1401.     When you start up Parse-O-Matic, you can specify the name of the output
  1402.     file on the command line.  For example:
  1403.     
  1404.     POM MYPOM.POM INPUT.TXT OUTPUT.TXT
  1405.     
  1406.     In this case, the output file is named OUTPUT.TXT.  All data from the
  1407.     output commands (OUT, OUTEND etc.) are sent to this file.  If you omit the
  1408.     output file name from the POM command, like this:
  1409.     
  1410.     POM MYPOM.POM INPUT.TXT
  1411.     
  1412.     then Parse-O-Matic assumes the output file is named POMOUT.TXT (in the
  1413.     current directory).
  1414.     
  1415.     -----------
  1416.     Basic Usage
  1417.     -----------
  1418.     
  1419.     Once the name of the output file has been determined, Parse-O-Matic will
  1420.     use that file until it is changed, using the OFILE command.  For example:
  1421.     
  1422.     OFILE "C:\XYZ.TXT"
  1423.     
  1424.     This will change the output file to C:\XYZ.TXT.  If the file already
  1425.     exists, it will be renamed with a BAK extension.  However, you can tell
  1426.     Parse-O-Matic to append to the end of an existing file by placing a plus
  1427.     sign in front of the file name:
  1428.     
  1429.     OFILE "+C:\XYZ.TXT"
  1430.     
  1431.  
  1432.  
  1433.                                                                              17
  1434.     (See "Appending to Output Files" and "POM and Wildcards" for additional
  1435.     details on appending to output files).
  1436.     
  1437.     -----------------------
  1438.     Closing the Output File
  1439.     -----------------------
  1440.     
  1441.     Sometimes you want your POM file to explicitly close the output file before
  1442.     doing additional processing.  By closing the file explicitly, you ensure
  1443.     that all output has been written to the disk.
  1444.     
  1445.     To explicitly close the output file, use OFILE's CLOSE subcommand:
  1446.     
  1447.     OFILE "(CLOSE)"
  1448.     
  1449.     It is rarely necessary to explicitly close the output file, since this is
  1450.     done automatically when Parse-O-Matic finishes processing.  You only need to
  1451.     do this if you suspect that a failure may occur between an OUT[END] command
  1452.     and the next OFILE command (or the completion of processing).
  1453.     
  1454.     ----------------
  1455.     Strong Deduction
  1456.     ----------------
  1457.     
  1458.     Sometimes you want to relate the name of the output file to the input file.
  1459.     For example, if the input file is XYZ.TXT, you might want to name the output
  1460.     file XYZ.OUT -- in other words, the same root name (XYZ) but a different
  1461.     extension (OUT).
  1462.     
  1463.     The OFILE command can do this with the DEDUCE subcommand, as follows:
  1464.     
  1465.     OFILE "(DEDUCE)" "OUT" "STRONG"
  1466.     
  1467.     The (DEDUCE) subcommand tells OFILE that you want it to use the same root
  1468.     name as the input file.  The "OUT" part of this example is the extension you
  1469.     want to use.  "STRONG" means that you want to override the existing output
  1470.     file, even if the user specified one on the command line.
  1471.     
  1472.     Here is another example:
  1473.     
  1474.     OFILE "(DEDUCE)" "CSV" "STRONG"
  1475.     
  1476.     This uses the same root name as the input file, but uses the CSV extension
  1477.     (CSV usually signifies a comma-separated-value file).  Once again, the
  1478.     "STRONG" parameter means that the new output file will be opened even if the
  1479.     user specified an output file on the POM command line.
  1480.     
  1481.  
  1482.  
  1483.  
  1484.  
  1485.  
  1486.  
  1487.  
  1488.                                                                              18
  1489.     --------------
  1490.     Weak Deduction
  1491.     --------------
  1492.     
  1493.     Sometimes you want to set the output file name only if the user has not
  1494.     specified one on the POM command line.  You can do this with OFILE's DEDUCE
  1495.     subcommand:
  1496.     
  1497.     OFILE "(DEDUCE)" "CSV" "WEAK"
  1498.     
  1499.     If the user ran POM with this command:
  1500.     
  1501.     POM MYFILE.POM ACCOUNT.DAT
  1502.     
  1503.     then the output file would be set to ACCOUNT.CSV.  However, if the user
  1504.     explicitly specified an output file:
  1505.     
  1506.     POM MYFILE.POM ACCOUNT.DAT MYOUTPUT.TXT
  1507.     
  1508.     then the weak OFILE command would be ignored and output would continue to
  1509.     be directed to the MYOUTPUT.TXT file.
  1510.     
  1511.     Weak deduction is generally used in the PROLOGUE section of a POM file.  It
  1512.     is particularly useful when wildcards are used (See "POM and Wildcards").
  1513.     Consider this POM command:
  1514.     
  1515.     POM MYFILE.POM *.DAT
  1516.     
  1517.     You could put the following OFILE command in the PROLOGUE:
  1518.     
  1519.     OFILE "(DEDUCE)" "TXT"        <-- "WEAK" is the default deduction
  1520.     
  1521.     This would create a separate output file for each file that is processed.
  1522.     So if you had three DAT files, named A.DAT, B.DAT and C.DAT, you would
  1523.     create three output files, named A.TXT, B.TXT and C.TXT.
  1524.     
  1525.     Because this is a weak deduction, the user is not forced to use your output
  1526.     method.  If the user typed the POM command this way:
  1527.     
  1528.     POM MYFILE.POM *.DAT MYOUTPUT.TXT
  1529.     
  1530.     then all the output (from all of the input files) would go to MYOUTPUT.TXT.
  1531.     
  1532.     NOTE:  When a user does not specify an output file, Parse-O-Matic
  1533.            temporarily assumes that the output file is named POMOUT.TXT. If the
  1534.            user actually types POMOUT.TXT on the command line, Parse-O-Matic
  1535.            treats it as if no output file name had been typed.
  1536.     
  1537.  
  1538.  
  1539.  
  1540.  
  1541.  
  1542.  
  1543.                                                                              19
  1544.     -------------------
  1545.     Appended Deductions
  1546.     -------------------
  1547.     
  1548.     An alternative to the DEDUCE subcommand is the +DEDUCE subcommand.  This
  1549.     will figure out the output file name as before, but all output will be
  1550.     appended to the end.  This is useful for daily processing when you want to
  1551.     accumulate data in your output file or files.  For example:
  1552.     
  1553.     OFILE "(+deduce)" "txt" "strong"     <-- Note that case does not matter
  1554.     
  1555.     If the user started POM with this command:
  1556.     
  1557.     POM MYFILE.POM ACCOUNT.DAT
  1558.     
  1559.     then the output file would be set to ACCOUNT.TXT, and all output would be
  1560.     placed at the end of the existing file of that name.
  1561.     
  1562.                             ---------------------------
  1563.                             The OUT and OUTEND Commands
  1564.                             ---------------------------
  1565.     
  1566.     FORMAT:        OUT[END] [value1 [comparator] value2] |output-picture
  1567.     
  1568.     PURPOSE:       The OUT command generates output without an end-of-line
  1569.                    (i.e. carriage return and linefeed characters).
  1570.                    The OUTEND command generates output and also adds an
  1571.                    end-of-line.
  1572.     
  1573.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1574.                    In the following explanation, we will demonstrate the
  1575.                    command using only the "literally identical" ("=")
  1576.                    comparator.
  1577.     
  1578.     When value1 equals value2, a line is sent to the output file, according to
  1579.     the output picture.  Within the output picture, all text is taken literally
  1580.     (i.e. " is taken to mean literally that -- a quotation mark character).
  1581.     
  1582.     The only exception to this is variable names, which are identified by the
  1583.     { and } characters.  For example, a POM file that contained the following
  1584.     single line:
  1585.     
  1586.     OUTEND "X" = "X" |{$FLINE}
  1587.     
  1588.     would simply output every line from the input file (not very useful!).
  1589.     
  1590.     The "X" = "X" part of the command is the comparison which controls when
  1591.     output occurs.  In the example above, both values being compared are the
  1592.     same, so output will always occur.
  1593.     
  1594.     You can not use substrings after the "|" marker.  Thus, the following line
  1595.     is NOT legal:  OUTEND $FLINE[1 3] = "IBM" |{$FLINE[1 15]}
  1596.     
  1597.  
  1598.                                                                              20
  1599.     The correct way to code this is as follows:
  1600.     
  1601.     SET CODE = $FLINE[1 15]
  1602.     OUTEND $FLINE[1 3] = "IBM" |{CODE}
  1603.     
  1604.     This outputs the first 15 characters of any line that contains the letters
  1605.     "IBM" in the first three positions.
  1606.     
  1607.     -----------------------
  1608.     Generating a Blank Line
  1609.     -----------------------
  1610.     
  1611.     To send a blank line to a text output file, specify OUTEND without any data
  1612.     following the | marker, as follows:
  1613.     
  1614.     OUTEND |
  1615.     
  1616.     --------------
  1617.     Missing Output
  1618.     --------------
  1619.     
  1620.     If you find that an OUT or OUTEND command is not displaying a variable, but
  1621.     puts "nothing" in its place, check the spelling of the variable name in each
  1622.     place it is used.  Consider this example:
  1623.     
  1624.     SET     varablex = $FLINE[1 12]
  1625.     OUTEND  |XX{variablex}ZZ
  1626.     
  1627.     The SET command spelled "variablex" incorrectly -- it left out the "i". When
  1628.     OUTEND encounters the variable named "variablex", it sees that it does not
  1629.     have a value, so it replaces it with "nothing", yielding the result "XXZZ".
  1630.     
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.                                                                              21
  1654.                                  ------------------
  1655.                                  The OUTHDG Command
  1656.                                  ------------------
  1657.     
  1658.     FORMAT:        OUTHDG value1
  1659.     
  1660.     PURPOSE:       OUTHDG is used to place text headers in your output.
  1661.     
  1662.     ALTERNATIVES:  The OUTEND command, used with PROLOGUE
  1663.     
  1664.     SEE ALSO:      "The PageLen Command" and "The OutPage Command"
  1665.     
  1666.     If you were parsing data to create an employee report, you might use OUTHDG
  1667.     like this:
  1668.     
  1669.     SET EMPNUM = $FLINE[ 1  5]
  1670.     SET NAME   = $FLINE[10 28]
  1671.     SET PHONE  = $FLINE[30 45]
  1672.     OUTHDG "EMPL#  NAME                PHONE NUMBER"
  1673.     OUTHDG "-----  ------------------- ------------"
  1674.     OUTEND |{EMPNUM} {NAME} {PHONE}
  1675.     
  1676.     The value following the OUTHDG command is sent to the output file only
  1677.     once.  That is to say, after an OUTHDG sends a value to the output file,
  1678.     subsequent encounters with that OUTHDG command are ignored -- unless the
  1679.     PAGELEN command is used.
  1680.     
  1681.     To specify a blank line in a heading, use the following command:  OUTHDG ""
  1682.     
  1683.     If your output is bound for a continuous-paper printer (e.g. a dot-matrix
  1684.     printer with tractor feed), you may find it useful to use one or more blank
  1685.     lines at the beginning of the header, in order to skip over the perforation
  1686.     in the paper.
  1687.     
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.                                                                              22
  1709.                                 -------------------
  1710.                                 The OUTPAGE Command
  1711.                                 -------------------
  1712.     
  1713.     FORMAT:        OUTPAGE  [value1 [comparison] value2]
  1714.     
  1715.     PURPOSE:       Sends a page eject to the output file (or device).
  1716.     
  1717.     NOTES:         For an explanation of comparators, see "Using Comparators".
  1718.     
  1719.     SEE ALSO:      "The Pagelen Command", "The OutHdg Command", "$LINECOUNTER"
  1720.     
  1721.     If the comparison in the OUTPAGE command is true, or if it is omitted,
  1722.     OUTPAGE will send a "page eject" to the output file or device.  (See
  1723.     "Sending Output to a Device")  Some exceptions apply, however.  The page
  1724.     eject is not sent under the following circumstances:
  1725.     
  1726.     - If the comparison is false (e.g. OUTPAGE "Y" = "N")
  1727.     
  1728.     - If the page length is set to "0" (the default).  Use the PAGELEN command
  1729.       to specify a different page length.
  1730.     
  1731.     - If the output file is not yet open.  That is to say, if no output has
  1732.       been sent to the output via one of the other output commands (e.g. OUT,
  1733.       OUTEND, OUTHDG), then OUTPAGE will do nothing. (See "How Parse-O-Matic
  1734.       Opens an Output File")
  1735.     
  1736.     - If the output is already at the top of a page.
  1737.     
  1738.     If form feeds are enabled (via the PAGELEN command), OUTPAGE sends a
  1739.     page eject by sending a Form Feed character (ASCII 12) to the output.
  1740.     
  1741.     If form feeds are not enabled, OUTPAGE sends blank lines (i.e. linefeeds)
  1742.     until the requisite number of lines appear on the page.
  1743.     
  1744.     OUTPAGE does NOT automatically place OUTHDG text at the top of the page.
  1745.     OUTHDG text is not "stored"; it is executed in the POM file at the place
  1746.     it occurs.  Here is an example of using OUTPAGE and OUTHDG together:
  1747.     
  1748.     PAGELEN "55" "Y"
  1749.     SET partnum = $FLINE[ 1  7]
  1750.     SET descrip = $FLINE[12 60]
  1751.     OUTPAGE partnum <> oldpartnum
  1752.     OUTHDG |PARTNUM  DESCRIPTION
  1753.     OUTHDG |-------  -----------
  1754.     OUTEND |{partnum}  {descrip}
  1755.     SET    oldpartnum = partnum
  1756.     
  1757.     This will generate a new page, complete with headings, when the partnum
  1758.     variable is different from the oldpartnum variable.  Also, because of the
  1759.     interaction between OUTHDG and PAGELEN, they headings will appear on a new
  1760.     page if you run out of room on the current page.
  1761.     
  1762.  
  1763.                                                                              23
  1764.                                 -------------------
  1765.                                 The PAGELEN Command
  1766.                                 -------------------
  1767.     
  1768.     FORMAT:        PAGELEN value1 [value2]
  1769.     
  1770.     PURPOSE:       The PAGELEN command specifies the length of the output page.
  1771.     
  1772.     PARAMETERS:    value1 is the page length
  1773.                    value2 specifies if form feeds should be used
  1774.     
  1775.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  1776.     
  1777.     DEFAULTS:      value2 = "Y"
  1778.     
  1779.     When text is sent to an output file by OUTHDG and OUTEND, the lines are
  1780.     counted.  The default value for page length is zero, which means that the
  1781.     output is a single page of infinite length.  As such, OUTHDG headings
  1782.     appear only the first time they are encountered, and OUTPAGE commands
  1783.     are ignored.
  1784.     
  1785.     If you specify a page length greater than zero, OUTHDG headings become
  1786.     re-enabled once the specified number of output lines have been generated,
  1787.     or after an OUTPAGE command is performed.  A typical value is as follows:
  1788.     
  1789.     PAGELEN "55"
  1790.     
  1791.     This is an ideal page length for most laser printers.  Dot matrix printers
  1792.     typically use a page length of 66.
  1793.     
  1794.     Parse-O-Matic inserts a "form feed" (ASCII 12) character between pages.
  1795.     You can turn this off, however, by specifying the page length this way:
  1796.     
  1797.     PAGELEN "66" "N"
  1798.     
  1799.     The "N" specification means, "No, don't use form feeds".  Another
  1800.     acceptable value is "Y", meaning "Yes, use form feeds", but since this is
  1801.     the default, you do not have to specify it.
  1802.     
  1803.     
  1804.     
  1805.  
  1806.  
  1807.  
  1808.  
  1809.  
  1810.  
  1811.  
  1812.  
  1813.  
  1814.  
  1815.  
  1816.  
  1817.  
  1818.                                                                              24
  1819.     ============================================================================
  1820.                                    INPUT COMMANDS
  1821.     ============================================================================
  1822.     
  1823.                                   ---------------
  1824.                                   The GET Command
  1825.                                   ---------------
  1826.     
  1827.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  1828.     
  1829.     FORMAT:        GET var1 value1 [value2]         (Variable length records)
  1830.                    GET var1 value1 "END" [value3]   (Delimiter-terminated data)
  1831.                    GET var1 "EOF"                   (Detects end-of-file)
  1832.     
  1833.     PURPOSE:       Manually reads bytes from the input file.
  1834.     
  1835.     RESTRICTIONS:  The input file must be described with CHOP or SPLIT.
  1836.     
  1837.     NOTES:         Data is normally read automatically from the input file.
  1838.                    GET is used only when you want precise control of the
  1839.                    reading process.  GET works only with files whose format
  1840.                    is defined by a CHOP or SPLIT command.  (You can read a
  1841.                    file a byte at a time by using CHOP 1-1 in your POM file.
  1842.                    You can also use CHOP 0 to do all reading manually.)
  1843.     
  1844.     SEE ALSO:      "The Chop Command" and "The Split Command"
  1845.     
  1846.     The GET command is especially helpful for:
  1847.     
  1848.     1) Variable length records
  1849.     2) Delimiter-terminated data (such as zero-terminated text strings)
  1850.     3) Text files with embedded binary data
  1851.     
  1852.     These methods are described in detail below.
  1853.     
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862.  
  1863.  
  1864.  
  1865.  
  1866.  
  1867.  
  1868.  
  1869.  
  1870.  
  1871.  
  1872.  
  1873.                                                                              25
  1874.     -----------------------
  1875.     Variable Length Records
  1876.     -----------------------
  1877.     
  1878.     FORMAT:        GET var1 value1 [value2]
  1879.     
  1880.     PURPOSE:       Reads a variable-length record.
  1881.     
  1882.     PARAMETERS:    var1    is the variable being set
  1883.                    value1  specifies how many bytes to read, expressed as:
  1884.                            A value in text format (example:  GET x "10")
  1885.                            A predefined data type (example:  GET x "INTEGER")
  1886.                            A value in byte format (example:  GET x len "BYTE")
  1887.                    value2  specifies the data representation used by value1
  1888.                            This can be "TEXT" (the default) or "BYTE"
  1889.                            May also include "STRICT" (the default) or "LOOSE"
  1890.     
  1891.     NUMERICS:      Tabs, spaces and commas are stripped from value1, if it is
  1892.                    numeric, and in text format
  1893.     
  1894.     DEFAULTS:      value2 = "TEXT"
  1895.     
  1896.     SEE ALSO:      "Predefined Data Types"
  1897.     
  1898.     GET can read up to 255 bytes into a variable, as specified by value1.
  1899.     For example:
  1900.     
  1901.     GET xyz "10"
  1902.     
  1903.     This reads 10 bytes from the input file into the xyz variable, and advances
  1904.     the file pointer.  That is to say, after the GET command shown above is
  1905.     executed, the next data Parse-O-Matic reads will be 10 bytes further along.
  1906.     
  1907.     If the requested number of bytes is not available in the input file,
  1908.     Parse-O-Matic terminates with an error message.
  1909.     
  1910.     In a typical application, variable-length data is preceded in the input
  1911.     file by a byte that gives its length.  You can read the length, then use
  1912.     it directly, as follows:
  1913.     
  1914.     GET len "1" "TEXT"               <-- Get the length byte
  1915.     GET xyz len "BYTE"               <-- Read in the data
  1916.     
  1917.     In the first command, the word "TEXT" means that the length specification
  1918.     (i.e. "1") is plain text.  ("TEXT" is the default, so you can omit it.)
  1919.     
  1920.     In the second command, GET reads len bytes from the input file.  The word
  1921.     "BYTE" means that the length specification is a binary number, not a text
  1922.     string.
  1923.     
  1924.     To clarify this, let us assume that the input file contains a length byte
  1925.     (say hex 4F, which equals 79 in decimal).  This is followed by 79 bytes of
  1926.     data.  The first GET command (GET len "1") reads in the length byte (hex 4F
  1927.  
  1928.                                                                              26
  1929.     or decimal 79).  The second GET command (GET xyz len "BYTE") reads 79 bytes
  1930.     and places the result in the xyz variable.
  1931.     
  1932.     The maximum variable length that a single GET command can handle is 255
  1933.     bytes (i.e. the largest number represented by a single byte).
  1934.     
  1935.     Here are some additional examples of the GET command:
  1936.     
  1937.     SAMPLE COMMAND     EXPLANATION
  1938.     -----------------  -----------
  1939.     GET x "5" "TEXT"   Reads 5 bytes into the x variable
  1940.     GET x "5"          Same as above (since "TEXT" is the default)
  1941.     GET x len          In this case, len must contain a text number (e.g. "7")
  1942.     GET x len "BYTE"   In this case, len must be a byte (i.e. binary format)
  1943.     
  1944.     When the number is in "TEXT" format, spaces and tabs are ignored. Thus, the
  1945.     following command is valid:
  1946.     
  1947.     GET abc " 5 " "TEXT"
  1948.     
  1949.     You can also specify the length of the data as a predefined data type (see
  1950.     "Predefined Data Types" and "The MakeData Command").  Some examples...
  1951.     
  1952.     SAMPLE COMMAND     EXPLANATION
  1953.     -----------------  -----------
  1954.     GET x "INTEGER"    Reads in an integer value (2 bytes long)
  1955.     GET x "SHORTINT"   Reads in a short integer value (1 byte long)
  1956.     GET x "BYTE"       Reads in a byte value (1 byte long)
  1957.     GET x "LONGINT"    Reads in a long integer (4 bytes long)
  1958.     GET x "REAL"       Reads in a real value (6 bytes long)
  1959.     GET x "REAL 2"     Same as above (the decimal precision value 2 is ignored)
  1960.     
  1961.     TECHNICAL NOTE:  In some applications, you will find that a variable-length
  1962.     record may be followed by a "noise" byte. This can occur if the program
  1963.     that created the input file "aligns data to word boundaries" and the record
  1964.     you are reading has an odd number of bytes.  In such case, your POM file
  1965.     must determine (using CALC commands) if the length byte is odd or even, and
  1966.     react accordingly.
  1967.     
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.  
  1982.  
  1983.                                                                              27
  1984.     -------------------------
  1985.     Delimiter-Terminated Data
  1986.     -------------------------
  1987.     
  1988.     FORMAT:        GET var1 value1 "END" [value3]
  1989.     
  1990.     PURPOSE:       Reads delimiter-terminated data from the input file.
  1991.     
  1992.     PARAMETERS:    var1    is the variable being set
  1993.                    value1  is the terminating character you are searching for
  1994.                    "END"   means you are searching for a terminating character
  1995.                    value3  is "I" (for Include) or "X" (for eXclude)
  1996.     
  1997.     DEFAULTS:      value3 = "X"
  1998.     
  1999.     ALTERNATIVES:  The PARSE and PEEL commands
  2000.                    The FINDPOSN command used with the COPY command
  2001.     
  2002.     One common way to represent variable-length text data in a file is to
  2003.     terminate the text string with the null (ASCII 0) character.  You can
  2004.     read in this kind of data with the GET command, as follows:
  2005.     
  2006.     GET abc #0 "END"           <-- #0 means ASCII zero (See "Values")
  2007.     
  2008.     This reads the input file until the null (ASCII 0) character is found, or
  2009.     until 255 characters have been read in (whichever comes first).
  2010.     
  2011.     The terminating character is not included in the string unless you
  2012.     explicitly request it.  There are two forms of GET command that control
  2013.     this behavior:
  2014.     
  2015.     GET abc #0 "END" "X"       <-- Exclude the terminating character (default)
  2016.     GET abc #0 "END" "I"       <-- Include the terminating character
  2017.     
  2018.     Here is a sample POM file that reads a data file that consists entirely of
  2019.     zero-terminated strings:
  2020.     
  2021.     CHOP   0                   <-- This means you will handle all file reading
  2022.     GET    abc #0 "END"        <-- Read in the data
  2023.     OUTEND |{abc}              <-- Send the data to the output file
  2024.     
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.                                                                              28
  2039.     ---------------------------------------
  2040.     Handling Long Delimiter-Terminated Data
  2041.     ---------------------------------------
  2042.     
  2043.     If some of the data is more than 255 characters long, you can handle it as
  2044.     follows:
  2045.     
  2046.     CHOP   0                   <-- Handle all file reading manually
  2047.     GET    data #0 "END" "I"   <-- Include the terminating character
  2048.     SETLEN len data            <-- Get the length of the string
  2049.     COPY   lastchar data len   <-- Get the last character
  2050.     BEGIN  lastchar = #0       <-- Test the last character
  2051.       DELETE data len          <-- Remove the last character (the terminator)
  2052.       OUTEND |{data}           <-- Output the string, and start a new line
  2053.     ELSE
  2054.       OUT    |{data}           <-- Output the string, but stay on the same line
  2055.     END
  2056.     
  2057.     All of the examples given above assume that the terminating character is
  2058.     ASCII 0 (i.e. #0), because this is by far the most common terminator.
  2059.     However, you can use other values, if required:
  2060.     
  2061.     GET data "X" "END"
  2062.     
  2063.     In actual usage, it is not likely that you will find data strings that are
  2064.     terminated by an "X" character, but the capability is there if the need
  2065.     arises.
  2066.     
  2067.     -------------------------
  2068.     Using GET with Text Files
  2069.     -------------------------
  2070.     
  2071.     While the GET command is normally used with a file which is CHOPped (see
  2072.     "The Chop Command"), you may occasionally find it useful with ordinary text
  2073.     files.  For example, an input file may be almost entirely text (i.e. each
  2074.     line ends with a carriage return and a linefeed), but may also contain some
  2075.     binary data.
  2076.     
  2077.     In such cases, you may find it useful to use the GET command to process the
  2078.     binary data.  However, since GET is not available under standard text
  2079.     processing, you must describe the file with the SPLIT command.  Here is an
  2080.     example which detects and extracts binary data until the character $FF is
  2081.     encountered:
  2082.     
  2083.     SPLIT    1-255                      <-- Process this as a SPLIT file
  2084.     BEGIN    $FLINE[1 10] = "Binary:"   <-- Detect the start of binary data
  2085.       BEGIN                             <-- Start of loop
  2086.         GET    x "1"                    <-- Get a byte
  2087.         OUT    |{x}                     <-- Send it to output
  2088.       AGAIN  x <> $FF                   <-- See if we are finished
  2089.     ELSE                                <-- Handle ordinary text
  2090.       OUTEND   |{$FLINE}                <-- Output ordinary text
  2091.     END                                 <-- End of BEGIN/ELSE/END code block
  2092.  
  2093.                                                                              29
  2094.     Note that SPLIT 1-255 does not mean that each text line is 255 characters
  2095.     long; it means that each line is UP TO 255 characters long.
  2096.     
  2097.     --------------------------
  2098.     End-of-File Considerations
  2099.     --------------------------
  2100.     
  2101.     When you ask the GET command to get something (e.g. a certain number of
  2102.     bytes), it will normally cause Parse-O-Matic to terminate if it reaches the
  2103.     end of the input file before it has fulfilled its mission.  The assumption
  2104.     here is that when you ask for something, you want precisely that -- not
  2105.     something less.
  2106.     
  2107.     However, in some parsing applications you do not know precisely what "lies
  2108.     ahead" in the input file.  In such cases, you may run up against the end of
  2109.     file unexpectedly.  GET provides two ways to handle this.
  2110.     
  2111.     The first method simply checks to see if you are already at the end of the
  2112.     file:
  2113.     
  2114.     GET x "EOF"
  2115.     
  2116.     This sets the x variable to "Y" (for Yes) if you are at the end of the input
  2117.     file.  Otherwise, it sets the x variable to "N" (for No).  Here is an
  2118.     example, which simply copies a file:
  2119.     
  2120.     CHOP     0             <-- Handle all file-reading manually
  2121.     BEGIN
  2122.       GET      x "EOF"     <-- Check if we're at the end of the input file
  2123.       BEGIN    x = "N"
  2124.         GET      byte "1"  <-- Get a byte
  2125.         OUT      |{byte}   <-- Send it to the output file
  2126.       END
  2127.     AGAIN    x = "N"
  2128.     
  2129.     An alternative method is to use a "LOOSE" GET command, as in this example:
  2130.     
  2131.     CHOP     0
  2132.     BEGIN
  2133.       GET      x "1" "TEXT LOOSE"
  2134.       OUT      |{x}
  2135.     AGAIN    x <> ""
  2136.     
  2137.     The LOOSE parameter tells Parse-O-Matic "don't terminate if you have less
  2138.     than the specified number of bytes".  (The default is "STRICT", but since it
  2139.     IS the default, you never actually have to include it in the command.)
  2140.     Thus, all of the following commands are valid:
  2141.     
  2142.     GET x $05 "BYTE LOOSE"    <-- Get from 0 to 5 bytes of data
  2143.     GET x $05 "BYTE STRICT"   <-- Get exactly 5 bytes of data, or terminate
  2144.     GET x "5" "TEXT LOOSE"    <-- Get from 0 to 5 bytes of data
  2145.     GET x "5" "LOOSE"         <-- Same as "TEXT LOOSE"
  2146.     GET x "1"                 <-- Same as "TEXT STRICT"
  2147.  
  2148.                                                                              30
  2149.                                 -------------------
  2150.                                 The GETTEXT Command
  2151.                                 -------------------
  2152.     
  2153.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  2154.     
  2155.     FORMAT:        GETTEXT var1 value1 [value2]
  2156.     
  2157.     PURPOSE:       Manually reads bytes from the input file, then converts
  2158.                    them into text format.
  2159.     
  2160.     PARAMETERS:    var1   is the variable being set
  2161.                    value1 is the predefined data type in the input file
  2162.                    value2 is the MAKETEXT "convert from" parameter
  2163.     
  2164.     DEFAULTS:      If value2 is omitted, it is assumed to be the same as value1
  2165.     
  2166.     NOTES:         Before studying this command, you should already be familiar
  2167.                    with the GET and MAKETEXT commands.
  2168.     
  2169.     SEE ALSO:      "Predefined Data Types"
  2170.     
  2171.     When reading a binary file, you frequently need to read numeric values then
  2172.     convert them to text.  For example:
  2173.     
  2174.     GET      x "WORD"             <-- Read a two-byte number from the file
  2175.     MAKETEXT y x "WORD"           <-- Convert it into text form
  2176.     
  2177.     You can do both of these operations at once, using the GETTEXT command:
  2178.     
  2179.     GETTEXT  y "WORD"
  2180.     
  2181.     This reads a "WORD" (two binary bytes) from the input file, and then
  2182.     converts it into text (e.g. "1234").
  2183.     
  2184.     You only need to use value2 if you are converting a number to a text-based
  2185.     data type such as "DATE".  For example:
  2186.     
  2187.     ZERODATE "1936" "1" "1"                <-- Set "day zero"
  2188.     GETTEXT  date "LONGINT" "DATE Y/M/?d"  <-- Get and convert a date
  2189.     
  2190.     The GETTEXT command is also helpful if you are reading text data from a
  2191.     fixed-length field, but it is padded with spaces or nulls:
  2192.     
  2193.     GETTEXT  x "80" "TRIMMED"
  2194.     
  2195.     This reads in 80 characters, then removes tabs, spaces and nulls from
  2196.     either end of the string.
  2197.     
  2198.  
  2199.  
  2200.  
  2201.  
  2202.  
  2203.                                                                              31
  2204.                                 --------------------
  2205.                                 The READNEXT Command
  2206.                                 --------------------
  2207.     
  2208.     FORMAT:        READNEXT [value [comparator] value]
  2209.     
  2210.     PURPOSE:       The READNEXT command gets the next line of the input file
  2211.                    (in other words, it replaces the current $FLINE), while
  2212.                    maintaining your place in the POM file.
  2213.     
  2214.     NOTES:         For an explanation of comparators, see "Using Comparators".
  2215.     
  2216.     SEE ALSO:      "The MinLen Command" and "Line Counters"
  2217.     
  2218.     READNEXT is helpful if you know for certain what type of information the
  2219.     next line will contain.  Here is an example:
  2220.     
  2221.     SET note = ""
  2222.     SET customer = $FLINE[1 20]
  2223.     BEGIN $FLINE ^ "See note below"
  2224.       READNEXT
  2225.       SET note = $FLINE[1 20]
  2226.     END
  2227.     OUTEND |{customer} {note}
  2228.     
  2229.     If the input line contains the words "See note below", Parse-O-Matic will
  2230.     read the next line of the input file (replacing the current $FLINE), thus
  2231.     obtaining the comment about the customer.
  2232.     
  2233.     ----------------------
  2234.     End of File Conditions
  2235.     ----------------------
  2236.     
  2237.     If you do a READNEXT at the end of the input file, READNEXT will set $FLINE
  2238.     to null ("").  The POM file will continue processing.
  2239.     
  2240.     --------------------
  2241.     Optional Comparisons
  2242.     --------------------
  2243.     
  2244.     READNEXT can make a comparison.  This is useful for skipping extraneous
  2245.     lines of input.  For example:
  2246.     
  2247.     READNEXT $FLINE[1 5] = "NOTE:"
  2248.     
  2249.     This obtains the next input line if the current input line starts with
  2250.     "NOTE:".
  2251.     
  2252.  
  2253.  
  2254.  
  2255.  
  2256.  
  2257.  
  2258.                                                                              32
  2259.     -------------------
  2260.     Ignoring Null Lines
  2261.     -------------------
  2262.     
  2263.     By default, READNEXT will read null lines from the input file.  If you want
  2264.     it to ignore null lines, you can use an optional parameter of the MINLEN
  2265.     command to specify a minimum length for the READNEXT command.  For details,
  2266.     see "The MinLen Command".
  2267.     
  2268.     If you are reading a DBF (DBase) file, you can not "ignore null lines",
  2269.     because the data is not in line format.  In such case, you must check a
  2270.     particular field to see if it is null.  (See "DBF Files")
  2271.     
  2272.     If you are using the CHOP or SPLIT commands, it may not be particularly
  2273.     useful to "ignore null lines", since by definition you are requesting a
  2274.     particular number of bytes each time the input is read.  Nevertheless,
  2275.     if you do a READNEXT at the end of the input file, READNEXT will set $FLINE
  2276.     to null (""), and continue processing the POM file.
  2277.     
  2278.     ------------------------
  2279.     Saving the Previous Line
  2280.     ------------------------
  2281.     
  2282.     When you do a READNEXT, there is no simple way to return to the previous
  2283.     line of the input file.  You could use the REWIND command, but if you need a
  2284.     line for other work, it is usually much easier to save a copy:
  2285.     
  2286.     SET note = ""
  2287.     SET customer = $FLINE[1 20]
  2288.     SET saveline = $FLINE
  2289.     BEGIN $FLINE ^ "See note below"
  2290.       READNEXT
  2291.       SET note = $FLINE[1 20]
  2292.     END
  2293.     SET    custnum = saveline[22 25]
  2294.     OUTEND |{custnum} {customer} {note}
  2295.     
  2296.     The example above is not very efficient; it would make more sense to extract
  2297.     custnum BEFORE you use READNEXT.  However, in some applications you may find
  2298.     it necessary to save $FLINE before doing a READNEXT.
  2299.     
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.  
  2311.  
  2312.  
  2313.                                                                              33
  2314.                                  ------------------
  2315.                                  The REWIND Command
  2316.                                  ------------------
  2317.     
  2318.     FORMAT:        REWIND [value1]
  2319.     
  2320.     PURPOSE:       REWIND backs up to an earlier point in the input file.
  2321.     
  2322.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  2323.     
  2324.     DEFAULTS:      If value1 is omitted, input file is rewound to the beginning
  2325.     
  2326.     RESTRICTIONS:  The input file must be described with CHOP or SPLIT.
  2327.     
  2328.     SEE ALSO:      "Using GET with Text Files"
  2329.     
  2330.     -----------------------
  2331.     Why REWIND is Necessary
  2332.     -----------------------
  2333.     
  2334.     Normally, when you process an input file, you read forward in the file.
  2335.     However, on occasion you may find it necessary to back up to an earlier
  2336.     point in the file.
  2337.     
  2338.     Here is a typical situation where this is necessary:  you are looking for
  2339.     one of several strings of data, and when you find one of them, you want to:
  2340.     
  2341.     - Back up in the input file, to the beginning of the string you found
  2342.     - Use DONE to start processing the POM file from the top
  2343.     
  2344.     Because you rewound, the processing will include the text that you found.
  2345.     This is a handy alternative to saving the text and appending it to the front
  2346.     of $FLINE -- see "The Leftover Technique" for an example of that method.
  2347.     
  2348.     In another situation, you need to know something near the middle or end of
  2349.     the file, and once you have found out what that is, you want to rewind to
  2350.     the beginning and start processing again.  This is known as "multiple-pass"
  2351.     processing, because you pass through the input file more than once.
  2352.     
  2353.     ------------
  2354.     Using REWIND
  2355.     ------------
  2356.     
  2357.     If REWIND is used without any parameters (or if you specify REWIND "0"),
  2358.     Parse-O-Matic resets the input file to the beginning.  This will usually be
  2359.     done in a BEGIN/END block, because if you reset the file each time you
  2360.     process the POM file, it will run forever.
  2361.     
  2362.     If REWIND is given a numeric parameter, it will back up that many bytes.
  2363.     (If you are processing a text file, remember to include two bytes for
  2364.     carriage return and linefeed, as necessary.)
  2365.     
  2366.  
  2367.  
  2368.                                                                              34
  2369.     If the REWIND command is asked to rewind before the beginning of the file,
  2370.     it simply resets to the top.  For example, if you have read 15 bytes out of
  2371.     the input file, and you issue the command REWIND "99", the next byte you
  2372.     read will be the first byte of the file.
  2373.     
  2374.     -------
  2375.     Example
  2376.     -------
  2377.     
  2378.     Consider this POM file:
  2379.     
  2380.     CHOP     0            <-- Handle all reading manually
  2381.     GET      x "1"        <-- Get a byte
  2382.     GET      x "1"        <-- Get another byte
  2383.     OUT      |{x}         <-- Output the byte
  2384.     REWIND   "1"          <-- Back up one byte
  2385.     GET      x "1"        <-- Get the same byte again
  2386.     OUT      |{x}         <-- Output the byte
  2387.     NEXTFILE              <-- Stop processing this input file
  2388.     
  2389.     The code shown above will output the second character of an input file
  2390.     twice, then stop -- not very useful, except as a demonstration!
  2391.     
  2392.     
  2393.     
  2394.  
  2395.  
  2396.  
  2397.  
  2398.  
  2399.  
  2400.  
  2401.  
  2402.  
  2403.  
  2404.  
  2405.  
  2406.  
  2407.  
  2408.  
  2409.  
  2410.  
  2411.  
  2412.  
  2413.  
  2414.  
  2415.  
  2416.  
  2417.  
  2418.  
  2419.  
  2420.  
  2421.  
  2422.  
  2423.                                                                              35
  2424.     ============================================================================
  2425.                                    INPUT FILTERS
  2426.     ============================================================================
  2427.     
  2428.                                  ------------------
  2429.                                  The MINLEN Command
  2430.                                  ------------------
  2431.     
  2432.     FORMAT:        MINLEN value1 [value2]
  2433.     
  2434.     PURPOSE:       MINLEN specifies the minimum length an input line must be to
  2435.                    be considered for parsing.
  2436.     
  2437.     PARAMETERS:    value1 is the minimum input line length
  2438.                    value2 is the minimum length for a READNEXT command
  2439.     
  2440.     NUMERICS:      Tabs, spaces and commas are stripped from value1 and value2
  2441.     
  2442.     DEFAULTS:      value2 = "0"
  2443.     
  2444.     SEE ALSO:      "The ReadNext Command"
  2445.     
  2446.     If you omit the MINLEN command, the minimum length is assumed to be 1.
  2447.     That is to say, all lines 1 character or longer will be processed and
  2448.     shorter lines (null lines in other words) will be ignored.
  2449.     
  2450.     MINLEN is useful for ignoring brief information lines that clutter up a
  2451.     report that you are parsing.  For example, in the sample file EXAMPL02.POM,
  2452.     the MINLEN command is set to 85 to ensure that all lines shorter than 85
  2453.     characters long will be ignored.  This simplifies the coding considerably.
  2454.     
  2455.     The longest allowable input line is 255 characters, unless you use the
  2456.     SPLIT or CHOP command (see "The Split Command" and "The Chop Command").
  2457.     
  2458.     The optional setting value2 specifies the minimum length for a READNEXT
  2459.     command.  If omitted, this value is assumed to be "0", meaning that
  2460.     READNEXT will, by default, read null lines.  If you set value2 to "1",
  2461.     READNEXT will keep reading until it finds an input line of 1 or more
  2462.     characters, or hits the end of file.  The value2 setting has no effect
  2463.     if you are reading a DBF (DBase) file.
  2464.     
  2465.  
  2466.  
  2467.  
  2468.  
  2469.  
  2470.  
  2471.  
  2472.  
  2473.  
  2474.  
  2475.  
  2476.  
  2477.  
  2478.                                                                              36
  2479.                                  ------------------
  2480.                                  The IGNORE Command
  2481.                                  ------------------
  2482.     
  2483.     FORMAT:        IGNORE value1 [comparator] value2
  2484.     
  2485.     PURPOSE:       When the comparison is true, the input line is ignored and
  2486.                    all further processing on the input line stops.
  2487.     
  2488.     NOTES:         For an explanation of comparators, see "Using Comparators".
  2489.     
  2490.     ALTERNATIVES:  The ACCEPT and BEGIN commands
  2491.     
  2492.     Here is a typical application of the IGNORE command:
  2493.     
  2494.     IGNORE $FLINE[3 9] ^ "Date"
  2495.     
  2496.     This skips any input line that contains the word "Date" between columns 3
  2497.     and 9 ($FLINE is the line just read from the input file).
  2498.     
  2499.                                  ------------------
  2500.                                  The ACCEPT Command
  2501.                                  ------------------
  2502.     
  2503.     FORMAT:        ACCEPT value1 [comparator] value2
  2504.     
  2505.     PURPOSE:       The ACCEPT command accepts the input line if the comparison
  2506.                    is true.  value2.  ACCEPT commands can be "clustered" to
  2507.                    allow a series of related tests.
  2508.     
  2509.     NOTES:         For an explanation of comparators, see "Using Comparators".
  2510.                    In the following explanation, we will demonstrate the
  2511.                    command using only the "literally identical" ("=")
  2512.                    comparator.
  2513.     
  2514.     ALTERNATIVES:  The IGNORE command
  2515.     
  2516.     If the entire POM file reads as follows:
  2517.     
  2518.     ACCEPT $FLINE[15 17] = "YES"
  2519.     OUTEND "X" = "X" |{$FLINE}
  2520.     
  2521.     then any input line that contains "YES" starting in column 15 is sent to
  2522.     the output file.  All other lines are ignored.
  2523.     
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531.  
  2532.  
  2533.                                                                              37
  2534.     -----------------
  2535.     Clustered Accepts
  2536.     -----------------
  2537.     
  2538.     Sometimes you have to check more than one value to see if the input line is
  2539.     valid.  You do this by using "clustered ACCEPTs", which are several ACCEPT
  2540.     commands in a row.
  2541.     
  2542.     Briefly stated, if you have several ACCEPTs in a row ("clustered"), they
  2543.     are all processed to determine if the input line is acceptable or not.  If
  2544.     even one ACCEPT matches up, the line is accepted.  To express this in more
  2545.     detail...
  2546.     
  2547.     When the comparison is true, the line is accepted, and processing of the
  2548.     POM file continues for that input line, even if the immediately following
  2549.     ACCEPTs do NOT produce a match.  After all, we've already got a match!
  2550.     
  2551.     If value1 does NOT contain value2, Parse-O-Matic looks at the next command
  2552.     in the POM file.  If it is not another ACCEPT, the input line is ignored.
  2553.     If it is another ACCEPT, maybe it will product a match -- so Parse-O-Matic
  2554.     moves to that command.
  2555.     
  2556.     The following POM file uses clustered ACCEPTs to accept any line that
  2557.     contains the name "FRED" or "MARY" between columns 5 and 8, or contains the
  2558.     word "MEMBER" between columns 20 and 25.
  2559.     
  2560.     SET    NAME = $FLINE[5 8]         <-- Set the variable
  2561.     ACCEPT NAME = "FRED"              <-- Look for FRED
  2562.     ACCEPT NAME = "MARY"              <-- Look for MARY
  2563.     ACCEPT $FLINE[20 25] = "MEMBER"   <-- Look for MEMBER
  2564.     OUTEND "X" = "X" |{$FLINE}        <-- Output the line if we get this far
  2565.     
  2566.     The following example will NOT work, however:
  2567.     
  2568.     ACCEPT $FLINE[20 25] = "MEMBER"
  2569.     SET    NAME = $FLINE[5 8]
  2570.     ACCEPT NAME = "FRED"
  2571.     ACCEPT NAME = "MARY"
  2572.     OUTEND "X" = "X" |{$FLINE}
  2573.     
  2574.     It will not work because the ACCEPTs are not clustered; if the first ACCEPT
  2575.     fails, the input line is rejected as soon as the SET command is
  2576.     encountered.  The next two ACCEPTs are not reached in such case.
  2577.     
  2578.     
  2579.     
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.                                                                              38
  2589.     ============================================================================
  2590.                                FLOW CONTROL COMMANDS
  2591.     ============================================================================
  2592.     
  2593.                                  -----------------
  2594.                                  The BEGIN Command
  2595.                                  -----------------
  2596.     
  2597.     FORMAT:        The basic format for the BEGIN command is as follows:
  2598.     
  2599.                    BEGIN value1 [comparator] value2
  2600.                    :
  2601.                    Dependant code
  2602.                    :
  2603.                    END
  2604.     
  2605.     PURPOSE:       If the comparison is true (e.g. value1 equals value2), then
  2606.                    the dependant code (the POM lines between the BEGIN and the
  2607.                    END) are executed.  If the comparison is false, then the
  2608.                    dependant code is skipped.
  2609.     
  2610.     NOTES:         For an explanation of comparators, see "Using Comparators".
  2611.                    In the following explanation, we will demonstrate the
  2612.                    command using only the "literally identical" ("=")
  2613.                    comparator.
  2614.     
  2615.     SEE ALSO:      "The Else Command" and "The Again Command"
  2616.     
  2617.     It is traditional in programming to indent code that appears in blocks
  2618.     such as Parse-O-Matic's BEGIN/END technique.  This makes the logic of
  2619.     the POM file easier for us to understand.  For example:
  2620.     
  2621.     BEGIN datatype = "Employee"
  2622.       SET phone    = $FLINE[ 1 10]
  2623.       SET address  = $FLINE[12 31]
  2624.     END
  2625.     
  2626.     BEGIN/END blocks can be nested.  That is to say, you can have BEGIN/END
  2627.     blocks inside other BEGIN/END blocks.  Here is an example, with arrows
  2628.     to indicate the levels of each BEGIN/END block...
  2629.     
  2630.     BEGIN datatype = "Employee"      <---------------------
  2631.       SET phone    = $FLINE[ 1 10]                        |
  2632.       SET address  = $FLINE[12 31]                        |
  2633.       SET areacode = phone[1 3]                           | First
  2634.       BEGIN areacode = "514"         <------- Second      | Level
  2635.         SET local = "Y"                     | Level       | Block
  2636.         SET tax   = "Y"              <------- Block       |
  2637.       END                                                 |
  2638.     END                              <---------------------
  2639.     
  2640.     In this case, the "inner" block (starting with BEGIN areacode = "514") is
  2641.     reached only if the "outer" block (BEGIN datatype = "Employee") is true.
  2642.  
  2643.                                                                              39
  2644.     If the outer block is false, the inner block is ignored.
  2645.     
  2646.     A nested BEGIN/END block must always be completely inside the outer block.
  2647.     Study the following (incorrect) example:
  2648.     
  2649.     BEGIN datatype = "Employee"             <----
  2650.       SET phone    = $FLINE[ 1 10]              |  First
  2651.       SET areacode = phone[1 3]                 |  Level
  2652.       BEGIN areacode = "514"         <---       |  Block?
  2653.         SET local = "Y"                 |       |
  2654.     END                                 |   <----
  2655.       SET tax = "Y"                     |
  2656.       END                            <---  Second Level Block?
  2657.     
  2658.     Parse-O-Matic does not pay attention to the indenting -- it is only a
  2659.     tradition we use to make the file easier to read.  The code will be
  2660.     understood this way:
  2661.     
  2662.     BEGIN datatype = "Employee"      <---------------------
  2663.       SET phone    = $FLINE[ 1 10]                        | First
  2664.       SET areacode = phone[1 3]                           | Level
  2665.       BEGIN areacode = "514"         <--- Second          | Block
  2666.         SET local = "Y"                 | Level           |
  2667.       END                            <--- Block           |
  2668.       SET tax = "Y"                                       |
  2669.     END                              <---------------------
  2670.     
  2671.     You can nest BEGIN/END blocks up to 25 deep -- although it is unlikely you
  2672.     will ever need that much nesting.  Here is an example of code that uses
  2673.     nesting up to three deep:
  2674.     
  2675.     BEGIN datatype = "Dog"           <----------------------------------
  2676.       SET breed = $FLINE[1 10]                                         | First
  2677.       BEGIN breed = "Collie"         <-----------------------          | Level
  2678.         SET noise = "Woof"                                  | Second   | Block
  2679.         BEGIN name = "Spot"          <------ Third          | Level    |
  2680.           SET attitude = "Friendly"        | Level          | Block    |
  2681.         END                          <------ Block          |          |
  2682.       END                            <-----------------------          |
  2683.       BEGIN breed = "Other"          <----------------------- Another  |
  2684.         SET noise = "Arf"                                   | Second   |
  2685.         SET attitude = "Unknown"                            | Level    |
  2686.       END                            <----------------------- Block    |
  2687.     END                              <----------------------------------
  2688.     
  2689.     Once again, the indentation is for clarity only and does not affect the
  2690.     way the POM file runs.  However, you will find that it makes your POM
  2691.     file much easier to understand.
  2692.     
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.                                                                              40
  2699.                                   ----------------
  2700.                                   The CALL Command
  2701.                                   ----------------
  2702.     
  2703.     FORMAT:        CALL value1
  2704.     
  2705.     PURPOSE:       Executes a subroutine (see "The Code Command")
  2706.     
  2707.     PARAMETERS:    value1 is the name of the subroutine
  2708.     
  2709.     The basic concepts of the CALL and CODE commands are discussed in the
  2710.     section entitled "The Code Command".
  2711.     
  2712.     --------------
  2713.     Variable CALLs
  2714.     --------------
  2715.     
  2716.     value1 will usually be a literal (e.g. CALL "Output Field"). However, it can
  2717.     also be a variable.  For example:
  2718.     
  2719.     IF       $FLINE[1] = "0" THEN routine = "Handle Type 0" ELSE "Handle Type 1"
  2720.     CALL     routine
  2721.     
  2722.     This calls the subroutine "Handle Type 0" if the first character of $FLINE
  2723.     is "0".  Otherwise, it calls the subroutine "Handle Type 1".  An alternative
  2724.     to this approach is:
  2725.     
  2726.     BEGIN    $FLINE[1] = "0"
  2727.       (code to handle Type 1 records)
  2728.     ELSE
  2729.       (code to handle other types of records)
  2730.     END
  2731.     
  2732.     Both methods accomplish the same thing, so the one you choose is largely a
  2733.     matter of personal preference.  In general, however, you should use CALL and
  2734.     CODE only when the same code is required in several different places in the
  2735.     POM file.  There are some exceptions however, as described in the next
  2736.     section...
  2737.     
  2738.     -----------------------------
  2739.     Making Your Technique Obvious
  2740.     -----------------------------
  2741.     
  2742.     Consider this example:
  2743.     
  2744.     APPEND   routine "Type" $FLINE[1]
  2745.     CALL     routine
  2746.     
  2747.     You can use this method to call subroutines named "Type0", "Type1", "Type2"
  2748.     and so on, according to the first character of $FLINE.  This can make your
  2749.     POM file a lot easier to understand.
  2750.     
  2751.  
  2752.  
  2753.                                                                              41
  2754.     Additionally, you may sometimes want to break up large parsing jobs into
  2755.     distinct pieces.  Thus, the main part of your POM file might read as
  2756.     follows:
  2757.     
  2758.     CALL     "Break Up Fields"
  2759.     CALL     "Clean Up Data"
  2760.     CALL     "Send to Output"
  2761.     
  2762.     If each of these steps is quite long and involved, your POM file may be
  2763.     easier to read and understand by using CALL, as shown, to portray the basic
  2764.     steps.
  2765.     
  2766.     ------------------------------
  2767.     Avoiding Unknown Code Sections
  2768.     ------------------------------
  2769.     
  2770.     If you attempt to call a subroutine that does not exist, Parse-O-Matic will
  2771.     terminate with an error message, saying it can not find the CODE section.
  2772.     It is a good idea to check for this possibility, as in this example:
  2773.     
  2774.     LOG      "012345" ~ $FLINE[1] "Unknown record type: " $FLINE[1]
  2775.     HALT     "012345" ~ $FLINE[1] "Unknown record type -- see processing log"
  2776.     APPEND   routine "Type" $FLINE[1]
  2777.     CALL     routine
  2778.     
  2779.     This will provide a more meaningful error message if the first character
  2780.     of $FLINE is not one that you expected (zero through five, in the example
  2781.     given above).
  2782.     
  2783.  
  2784.  
  2785.  
  2786.  
  2787.  
  2788.  
  2789.  
  2790.  
  2791.  
  2792.  
  2793.  
  2794.  
  2795.  
  2796.  
  2797.  
  2798.  
  2799.  
  2800.  
  2801.  
  2802.  
  2803.  
  2804.  
  2805.  
  2806.  
  2807.  
  2808.                                                                              42
  2809.                                   ----------------
  2810.                                   The CODE Command
  2811.                                   ----------------
  2812.     
  2813.     FORMAT:        The format of a subroutine is as follows:
  2814.     
  2815.                    CODE value1
  2816.                    :
  2817.                    Code run when this subroutine is invoked by the CALL command
  2818.                    :
  2819.                    END
  2820.     
  2821.     PURPOSE:       Defines a subroutine
  2822.     
  2823.     PARAMETERS:    value1 is the name of the subroutine
  2824.     
  2825.     NOTES:         value1 can be up to 255 characters long and may contain any
  2826.                    characters (including spaces).  Case is not important, so
  2827.                    "Read New Data" is treated the same as "READ NEW DATA".
  2828.                    Leading and trailing spaces and tabs are ignored.
  2829.     
  2830.     Subroutines are useful when a POM file has to perform the same series of
  2831.     commands in several different circumstances.  Consider this POM file:
  2832.     
  2833.     SET      field = $FLINE[10 20]  <-- Get a field
  2834.     CALL     "Output Date Field"    <-- Run a subroutine
  2835.     SET      field = $FLINE[30 40]  <-- Get a field
  2836.     CALL     "Output Date Field"    <-- Run a subroutine
  2837.     CODE     "Output Date Field"    <-- Start of subroutine     <-+
  2838.       CHANGE   field " " "/"        <-- Correct date format       |
  2839.       CHANGE   field "\" "/"        <-- Correct date format       |
  2840.       CHANGE   field "-" "/"        <-- Correct date format       | Subroutine
  2841.       CVTCASE  field field          <-- Convert to uppercase      |
  2842.       OUTEND   |{field}             <-- Output the field          |
  2843.     END                             <-- End of subroutine       <-+
  2844.     
  2845.     In this example, the subroutine (named "Output Date Field") tidies up the
  2846.     data before sending it to the output file.  For example, if the date field
  2847.     is "10 31 98", it is converted to "10/31/98".
  2848.     
  2849.     As you can see, subroutines can reduce the number of lines in a POM file.
  2850.     Also, if you give your subroutines meaningful names, your POM file will be
  2851.     much easier to understand.
  2852.     
  2853.     Subroutines also make it easier to update a POM file.  For example, if you
  2854.     noticed that the date field is sometimes delimited with the "plus" symbol,
  2855.     you could simply add the line  CHANGE field "+" "/"  to the "Output Date
  2856.     Field" subroutine.  In other words, you would add a single line of code
  2857.     instead of several lines.
  2858.     
  2859.     Subroutines are ignored by Parse-O-Matic unless they are explicitly invoked
  2860.     by a CALL command.
  2861.     
  2862.  
  2863.                                                                              43
  2864.     --------------------------
  2865.     Performance Considerations
  2866.     --------------------------
  2867.     
  2868.     If you have a POM file with a lot of subroutines, you can improve its
  2869.     performance slightly by moving all the CODE sections to the end of the file,
  2870.     and placing a DONE command in front of them.  This saves Parse-O-Matic the
  2871.     trouble of reading through them each time it processes a line.
  2872.     
  2873.     -----------------------
  2874.     Nested Subroutine Calls
  2875.     -----------------------
  2876.     
  2877.     You can call a subroutine from within a subroutine.  For example:
  2878.     
  2879.     CODE     "Clean Up Date Field"
  2880.       CHANGE   field " " "/"
  2881.       CHANGE   field "\" "/"
  2882.       CHANGE   field "-" "/"
  2883.       CVTCASE  field field
  2884.     END
  2885.     CODE     "Output Date Field"
  2886.       CALL     "Clean Up Date Field"
  2887.       OUTEND   |{field}
  2888.     END
  2889.     
  2890.     The second subroutine ("Output Date Field") calls the first subroutine
  2891.     ("Clean Up Date Field").  This feature is useful if several subroutines
  2892.     require the same processing.
  2893.     
  2894.     You must be careful not to have circular references (a subroutine that calls
  2895.     a subroutine which in turn calls the first subroutine).  This will call
  2896.     Parse-O-Matic to fail.
  2897.     
  2898.     Subroutine calls can be nested up to 25 deep.  That is to say, a subroutine
  2899.     can call a second subroutine, which can call a third subroutine, and so on,
  2900.     all the way up the 24th subroutine calling the 25th subroutine.  It is,
  2901.     however, unlikely that you will ever nest subroutines more than two or three
  2902.     deep.
  2903.     
  2904.     ----------------------
  2905.     Variable Code Sections
  2906.     ----------------------
  2907.     
  2908.     You may be wondering if you can place a variable in the value1 position of
  2909.     the CODE command, just as you can have a variable CALL command.  While it is
  2910.     possible to do so (i.e. Parse-O-Matic will not fail), we do not officially
  2911.     support this usage, as we see no reason for it.  If you do find a reason for
  2912.     it, make sure that the variable is first converted to uppercase.
  2913.     
  2914.  
  2915.  
  2916.  
  2917.  
  2918.                                                                              44
  2919.     ---------------------------------
  2920.     A Note to Experienced Programmers
  2921.     ---------------------------------
  2922.     
  2923.     Experienced programmers of other languages (e.g. Pascal, C, Basic, etc.) may
  2924.     wonder if there is a way to pass one or more variables to a subroutine.
  2925.     Parse-O-Matic does not currently support traditional features such as
  2926.     functions, variable-passing or local variables. These features (and other
  2927.     niceties such as code libraries) may be added in a later release.
  2928.     Parse-O-Matic's design is guided primarily by customer demand.
  2929.     
  2930.                                   ----------------
  2931.                                   The ELSE Command
  2932.                                   ----------------
  2933.     
  2934.     FORMAT:        The format of a BEGIN/ELSE/END block is as follows:
  2935.     
  2936.                    BEGIN value1 [comparator] value2
  2937.                    :
  2938.                    Code that is run if the comparison is true
  2939.                    :
  2940.                    ELSE
  2941.                    :
  2942.                    Code that is run if the comparison is false
  2943.                    :
  2944.                    END
  2945.     
  2946.     PURPOSE:       The ELSE command tells Parse-O-Matic to execute the
  2947.                    following block of code (up until the END command) if the
  2948.                    corresponding BEGIN comparison is NOT true.
  2949.     
  2950.     NOTES:         The ELSE command is not the same as the ELSE used to pad the
  2951.                    IF statement (e.g. IF xyz = "3" THEN x = "Y" ELSE "N").  In
  2952.                    the IF command, ELSE makes the statement more clear, but it
  2953.                    can be omitted (e.g. IF $FLINE[1] "3" x "Y" "N").
  2954.     
  2955.     Here is an example of a BEGIN/ELSE/END block:
  2956.     
  2957.     BEGIN $FLINE[1 10] = "JOHN SMITH"
  2958.       SET x = "This is John"
  2959.     ELSE
  2960.       SET x = "This is not John"
  2961.     END
  2962.     
  2963.     If you are using several levels of nesting, it is a good idea to indent
  2964.     your code to show the relationship of the BEGIN, ELSE and END statements:
  2965.     
  2966.  
  2967.  
  2968.  
  2969.  
  2970.  
  2971.  
  2972.  
  2973.                                                                              45
  2974.     BEGIN datatype = "Dog"           <----------------------------------
  2975.       SET breed = $FLINE[1 10]                                         | First
  2976.       BEGIN breed = "Collie"         <-----------------------          | Level
  2977.         SET noise = "Woof"                                  | Second   | Block
  2978.         BEGIN name = "Spot"          <------ Third          | Level    |
  2979.           SET attitude = "Friendly"        | Level          | Block    |
  2980.         END                          <------ Block          |          |
  2981.       ELSE                                                  |          |
  2982.         SET noise = "Arf"                                   |          |
  2983.         SET attitude = "Unknown"                            |          |
  2984.       END                            <-----------------------          |
  2985.     END                              <----------------------------------
  2986.     
  2987.     The ELSE is at "Level 2".  This is because there are three BEGINs ahead of
  2988.     it, but only one END (3 - 1 = 2).
  2989.     
  2990.                                   ---------------
  2991.                                   The END Command
  2992.                                   ---------------
  2993.     
  2994.     FORMAT:        END
  2995.     
  2996.     PURPOSE:       Marks the end of a BEGIN, PROLOGUE or EPILOGUE code block.
  2997.     
  2998.     The END command marks the end of a "code block".  A code block is a series
  2999.     of lines in a POM file that may be run if the conditions are right.
  3000.     
  3001.     For a more detailed discussion of the END command, see the following
  3002.     sections:
  3003.     
  3004.     - "The Begin Command"
  3005.     
  3006.     - "The Prologue Command"
  3007.     
  3008.     - "The Epilogue Command"
  3009.  
  3010.  
  3011.  
  3012.  
  3013.  
  3014.  
  3015.  
  3016.  
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.                                                                              46
  3029.                                  -----------------
  3030.                                  The AGAIN Command
  3031.                                  -----------------
  3032.     
  3033.     FORMAT #1:     BEGIN [value1 [comparator] value2]
  3034.                    :
  3035.                    Code executed if the BEGIN comparison is true or omitted
  3036.                    :
  3037.                    AGAIN [value1 [comparator] value2]
  3038.     
  3039.     FORMAT #2:     BEGIN value1 [comparator] value2
  3040.                    :
  3041.                    Code executed if the BEGIN comparison is true
  3042.                    :
  3043.                    ELSE
  3044.                    :
  3045.                    Code executed if the BEGIN comparison is false
  3046.                    :
  3047.                    AGAIN [value1 [comparator] value2]
  3048.     
  3049.     PURPOSE:       Controls the repetition of a BEGIN block.
  3050.     
  3051.     NOTES:         For an explanation of comparators, see "Using Comparators".
  3052.     
  3053.     SEE ALSO:      "The ReadNext Command", "The Begin Command", "The Else
  3054.                    Command" and "Uninitialized and Persistent Variables"
  3055.     
  3056.     DEFAULTS:      If the comparison part of the AGAIN command is omitted:
  3057.                    - AGAIN repeats if the BEGIN comparison was true or omitted
  3058.                    - AGAIN does not repeat if the BEGIN comparison was false
  3059.     
  3060.     ADVISORY:      If you are familiar with other computer languages, you may
  3061.                    be tempted to use AGAIN to create loops when none are
  3062.                    required.  Remember that a POM file is repeated (i.e.
  3063.                    looped) each time a record or line is read from the input
  3064.                    file.  The AGAIN command is most appropriate when you have
  3065.                    input records with a variable number of items.
  3066.     
  3067.     The AGAIN command allows you to implement "loops".  A loop is a section of
  3068.     code that can be repeated one or more times.
  3069.     
  3070.     AGAIN returns to the corresponding BEGIN if the comparison is true, or if
  3071.     it is omitted.  Since the BEGIN can also have a comparison, and can be used
  3072.     with the ELSE command, this allows many variations:
  3073.     
  3074.     COMMAND ARRANGEMENT             EFFECT
  3075.     ------------------------------  -----------------------------------------
  3076.     BEGIN               AGAIN       Loops forever
  3077.     BEGIN comp          AGAIN       Loops until the BEGIN comparison is false
  3078.     BEGIN               AGAIN comp  Loops until the AGAIN comparison is false
  3079.     BEGIN comp          AGAIN comp  Loops until either comparison is false
  3080.     BEGIN comp   ELSE   AGAIN comp  Loops until either comparison is false
  3081.     BEGIN comp   ELSE   AGAIN       Loops until the BEGIN comparison is false
  3082.  
  3083.                                                                              47
  3084.     In the last two examples, the ELSE code is run when the BEGIN comparison is
  3085.     false, then processing continues on the POM line after the AGAIN command.
  3086.     When a BEGIN comparison is false, the comparison (if any) of the AGAIN
  3087.     command is not evaluated.
  3088.     
  3089.     To put it another way:  the AGAIN comparison is considered only if the
  3090.     BEGIN comparison is true or omitted.
  3091.     
  3092.     ------------------------------------
  3093.     Using AGAIN for Variable-Length Data
  3094.     ------------------------------------
  3095.     
  3096.     Let us say you have a text file that contains the names of people belonging
  3097.     to various clubs.  The file lists the name of the club, then the number of
  3098.     people in each club, and then the names:
  3099.     
  3100.     Chess Club
  3101.     3
  3102.     John Smith
  3103.     Mary Jones
  3104.     Fred Williams
  3105.     Hopscotch Club
  3106.     0
  3107.     Tennis Club
  3108.     2
  3109.     Jack Martin
  3110.     Debbie Harris
  3111.     
  3112.     You could process this input file with the following POM file:
  3113.     
  3114.     PAD      $FLINE "R" " " "17"      <-- Pad the club name out with spaces
  3115.     OUT      |{$FLINE}                <-- Send the club name to the output file
  3116.     READNEXT                          <-- Get the number of members
  3117.     SET      members  = $FLINE        <-- Remember this number
  3118.     BEGIN    members  = "0"           <-- Check if we have any members
  3119.       OUT      |(None)                <-- Report if we have no members
  3120.     ELSE                              <-- If we have members, do the next part
  3121.       SET      count    = "0"         <-- Initialize a counter
  3122.       BEGIN                           <-- Start the loop
  3123.         READNEXT                      <-- Get the person's name
  3124.         SET    count = count+         <-- Count this person
  3125.         OUT    |{$FLINE}              <-- Send the name to the file
  3126.         OUT    count #< members |/    <-- Add a separator if not the last name
  3127.       AGAIN    count #< members       <-- Go back if we have more members
  3128.     END                               <-- Corresponds to the first BEGIN
  3129.     OUTEND  |                         <-- Start a new line after each club
  3130.     
  3131.     This POM file would generate the following output:
  3132.     
  3133.     Chess Club       John Smith/Mary Jones/Fred Williams
  3134.     Hopscotch Club   (None)
  3135.     Tennis Club      Jack Martin/Debbie Harris
  3136.     
  3137.  
  3138.                                                                              48
  3139.     ------------------------------
  3140.     Pointless Command Combinations
  3141.     ------------------------------
  3142.     
  3143.     Some combinations of BEGIN, ELSE and AGAIN are pointless.  The following
  3144.     command arrangements contain code that is never run:
  3145.     
  3146.     COMMAND ARRANGEMENT             NOTE
  3147.     ------------------------------  ------------------------------------------
  3148.     BEGIN        ELSE   AGAIN comp  The ELSE portion is never executed
  3149.     BEGIN        ELSE   AGAIN       Loops forever; the ELSE portion never runs
  3150.     
  3151.     --------
  3152.     Examples
  3153.     --------
  3154.     
  3155.     Either of these two POM files will read a text file and ignore any lines
  3156.     that contain the words "COW":
  3157.     
  3158.     Using the AGAIN Command       Using the IGNORE Command
  3159.     -----------------------       ------------------------
  3160.     BEGIN $FLINE ^ "COW"          IGNORE $FLINE ^ "COW"
  3161.       READNEXT                    OUTEND |{$FLINE}
  3162.     AGAIN
  3163.     OUTEND |{$FLINE}
  3164.     
  3165.     The shorter POM file is more efficient, but the results would be the
  3166.     roughly the same for both.  Remember that a POM file is processed each
  3167.     time Parse-O-Matic reads an input record (or line), so the second version
  3168.     is, in effect, looping as many times as there are records in the file.
  3169.     
  3170.     The following POM file will read one line from a file, then send the string
  3171.     [6]123[7]123[6]123[7]123 to the output file:
  3172.     
  3173.     SET      z = "0"
  3174.     BEGIN                      <-----------------------------
  3175.       SET      y = "5"                                      | First
  3176.       BEGIN    y <> "7"        <------------------          | Level
  3177.         SET      x = "0"                         | Second   | (Outermost)
  3178.         SET      y = y+                          | Level    | Loop
  3179.         APPEND   s s "[" y "]"                   | Loop     |
  3180.         BEGIN    x <> "3"      <--------         |          |
  3181.           SET      x = x+              | Third   |          |
  3182.           APPEND   s s x               | Level   |          |
  3183.         AGAIN                  <--------         |          |
  3184.       AGAIN                    <------------------          |
  3185.       SET     z = z+                                        |
  3186.     AGAIN   z <> "2"           <-----------------------------
  3187.     OUTEND  |{s}
  3188.     NEXTFILE
  3189.     
  3190.  
  3191.  
  3192.  
  3193.                                                                              49
  3194.     The third level (innermost) loop ... generates 123
  3195.     The second level (middle) loop ..... generates [6]123[7]123
  3196.     The first level (outermost) loop ... generates [6]123[7]123[6]123[7]123
  3197.     
  3198.     The following POM file will read one line from a file, then send the
  3199.     string "XXXY" to the output file:
  3200.     
  3201.     SET      z = "0"           <-- Initialize a counter
  3202.     SET      s = ""            <-- Initialize the string we will output
  3203.     BEGIN    z < "3"           <-- Check if the counter has reached "3"
  3204.       SET      z = z+          <-- Add one to the counter
  3205.       APPEND   s s "X"         <-- Add an "X" to the end of the output string
  3206.     ELSE                       /__ The ELSE section is run when
  3207.       APPEND   s s "Y"         \   the BEGIN comparison is false
  3208.     AGAIN                      <-- Go back to the BEGIN
  3209.     OUTEND   |{s}              <-- Continue here after the ELSE portion
  3210.     NEXTFILE                   <-- Stop reading the input file
  3211.     
  3212.                                   ----------------
  3213.                                   The DONE Command
  3214.                                   ----------------
  3215.     
  3216.     FORMAT:        DONE [value1 [comparator] value2]
  3217.     
  3218.     PURPOSE:       The DONE command will discontinue processing the POM file
  3219.                    and proceed to the next input line, whereupon the POM file
  3220.                    will restart at the top.
  3221.     
  3222.     NOTES:         For an explanation of comparators, see "Using Comparators".
  3223.                    In the following explanation, we will demonstrate the
  3224.                    command using only the "literally identical" ("=")
  3225.                    comparator.
  3226.     
  3227.     ALTERNATIVES:  The NEXTFILE, IGNORE and ACCEPT commands
  3228.     
  3229.     The DONE command is most useful when you have a long series of BEGIN/END
  3230.     blocks which make a related comparison.  For example:
  3231.     
  3232.  
  3233.  
  3234.  
  3235.  
  3236.  
  3237.  
  3238.  
  3239.  
  3240.  
  3241.  
  3242.  
  3243.  
  3244.  
  3245.  
  3246.  
  3247.  
  3248.                                                                              50
  3249.     SET   salesrep = $FLINE[11 50]
  3250.     SET   region   = $FLINE[ 1  2]
  3251.     BEGIN region = "US"
  3252.       OUTEND |Sales representative for U.S.A.: {salesrep}
  3253.       DONE
  3254.     END
  3255.     BEGIN region = "CN"
  3256.       OUTEND |Sales representative for Canada: {salesrep}
  3257.       DONE
  3258.     END
  3259.     BEGIN region = "EU"
  3260.       OUTEND |Sales representative for Europe: {salesrep}
  3261.       DONE
  3262.     END
  3263.     :
  3264.     etc.
  3265.     
  3266.     As you can see, if one of the BEGIN comparisons is true, all of the
  3267.     following ones will inevitably be false.  Rather than processing all the
  3268.     others, you can use the DONE command to bail out and get ready for the
  3269.     next input line.
  3270.     
  3271.     The DONE command provides two benefits:
  3272.     
  3273.     - It can speed up processing slightly
  3274.     - It makes full traces easier to understand
  3275.     
  3276.     For an explanation of traces, see the section entitled "Tracing".
  3277.     
  3278.     Unless you use a comparison (explained later), the DONE command is useful
  3279.     only inside BEGIN/ELSE/END blocks.  If you write a POM file like this:
  3280.     
  3281.     SET custnum  = $FLINE[ 1 10]
  3282.     SET custname = $FLINE[11 50]
  3283.     DONE
  3284.     OUTEND |{custname} {custnum}
  3285.     
  3286.     then the OUTEND statement will NEVER be reached.
  3287.     
  3288.     Here is how you specify a comparison for the DONE command:
  3289.     
  3290.     DONE $FLINE = "End of Data"
  3291.     
  3292.     This discontinues the POM file, and proceeds to the next input line, if the
  3293.     current input line ($FLINE) is "End of Data".
  3294.     
  3295.  
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.  
  3302.  
  3303.                                                                              51
  3304.                                 --------------------
  3305.                                 The NEXTFILE Command
  3306.                                 --------------------
  3307.     
  3308.     FORMAT:        NEXTFILE [value [comparator] value]
  3309.     
  3310.     PURPOSE:       NEXTFILE discontinues processing the current input file and
  3311.                    proceeds to the next one, restarting the POM file from the
  3312.                    top.
  3313.     
  3314.     NOTES:         For an explanation of comparators, see "Using Comparators".
  3315.                    In the following explanation, we will demonstrate the
  3316.                    command using only the "literally identical" ("=")
  3317.                    comparator.
  3318.     
  3319.     ALTERNATIVES:  The HALT command
  3320.     
  3321.     The NEXTFILE command is useful when you process multiple input files (see
  3322.     "POM and Wildcards").  Here is an example, which we will call TEST.POM:
  3323.     
  3324.     BEGIN $FLINE = "End of Data"
  3325.       OUTEND |{numlines} lines of data printed
  3326.       SET    numlines = ""
  3327.       NEXTFILE
  3328.     END
  3329.     SET    numlines = numlines+
  3330.     OUTEND |{$FLINE}
  3331.     
  3332.     Let's say you have three text files: DATA1.XYZ, DATA2.XYZ and DATA3.XYZ.
  3333.     The last line of each file says "End of Data".  You could copy all three
  3334.     files to the file OUTPUT.TXT with this command:
  3335.     
  3336.     POM TEST.POM DATA?.XYZ OUTPUT.TXT
  3337.     
  3338.     This would copy the data from each file, but when it gets to the line
  3339.     reading "End of Data", it records the number of lines of data that were
  3340.     printed.  Any lines after the "End of Data" line are skipped, because of
  3341.     the NEXTFILE command.
  3342.     
  3343.     The NEXTFILE command can specify a comparison.  Here is an example:
  3344.     
  3345.     NEXTFILE $FLINE = "End of Data"
  3346.     OUTEND |{$FLINE}
  3347.     
  3348.     Assuming the same input files (DATA1.XYZ etc.), and using the same POM
  3349.     command as last time, this POM file would simply copy up to (but not
  3350.     including" the line that reads "End of Data" in each input file.
  3351.     
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.                                                                              52
  3359.                                   ----------------
  3360.                                   The HALT Command
  3361.                                   ----------------
  3362.     
  3363.     FORMAT:        HALT value1 comparison value2 value3 [value4]
  3364.     
  3365.     PURPOSE:       The HALT command will terminate Parse-O-Matic processing if
  3366.                    the comparison is true.
  3367.     
  3368.     PARAMETERS:    value1 is any value
  3369.                    value2 is any value
  3370.                    value3 is the message to be displayed
  3371.                    value4 is the optional error level (between 100 to 199)
  3372.     
  3373.     NUMERICS:      Tabs, spaces and commas are stripped from value4
  3374.     
  3375.     ALTERNATIVES:  The NEXTFILE command
  3376.     
  3377.     SEE ALSO:      "The MsgWait Command"
  3378.     
  3379.     Here is an example of the HALT command:
  3380.     
  3381.     HALT sales = "0" "Zero sales!"
  3382.     
  3383.     If the variable named sales is "0", Parse-O-Matic will display an error
  3384.     box reading "Zero sales!" and terminate after you have pressed a key.  A
  3385.     copy of the message is also placed in the processing log POMLOG.TXT (see
  3386.     "Logging").
  3387.     
  3388.     When a HALT condition occurs, Parse-O-Matic terminates with a DOS error
  3389.     level of 100.  You can specify a different value, using value4.  This is
  3390.     useful if you are calling Parse-O-Matic from a batch file or application
  3391.     program and want to handle different errors in different ways.
  3392.     
  3393.     You can set value4 to any number between 100 and 199.  Consider these
  3394.     examples:
  3395.     
  3396.     HALT sales    = "0" "Zero sales"     "150"
  3397.     HALT sales[1] = "-" "Negative sales" "160"
  3398.     
  3399.     This terminates Parse-O-Matic with an error level of 150 if sales are zero.
  3400.     If the first character of sales is a minus sign, Parse-O-Matic terminates
  3401.     with an error level of 160.
  3402.     
  3403.     When coding batch files, remember that the IF ERRORLEVEL command is
  3404.     considered "True" if the error is the specified value or higher.  This
  3405.     means you should always test the higher value first.  See your operating
  3406.     system manual for details.
  3407.     
  3408.  
  3409.  
  3410.  
  3411.  
  3412.  
  3413.                                                                              53
  3414.                                 --------------------
  3415.                                 The PROLOGUE Command
  3416.                                 --------------------
  3417.     
  3418.     FORMAT:        The format for PROLOGUE (used with the END command) is:
  3419.     
  3420.                    PROLOGUE
  3421.                    :
  3422.                    Dependant code
  3423.                    :
  3424.                    END
  3425.     
  3426.     PURPOSE:       PROLOGUE defines dependant code which is run before the
  3427.                    first line of the input file is read.
  3428.     
  3429.     SEE ALSO:      "The Epilogue Command"
  3430.     
  3431.     PROLOGUE can be used to set up some variables, or set up a heading --
  3432.     anything you only want to do once per input file, at the very start.
  3433.     
  3434.     Here is an example of the PROLOGUE command:
  3435.     
  3436.     PROLOGUE
  3437.       SET both  = "B"
  3438.       SET space = " "
  3439.     END
  3440.     SET    firstname = $FLINE[ 1 10]
  3441.     SET    lastname  = $FLINE[15 25]
  3442.     TRIM   firstname both space
  3443.     TRIM   lastname  both space
  3444.     OUTEND |{firstname} {lastname}
  3445.     
  3446.     When the input file is first opened, the PROLOGUE section sets the
  3447.     variables "both" and "space".  Once they're set, you don't have to change
  3448.     them (since you are just using them to make the code easier to read).  Thus,
  3449.     it makes sense to set them only at the beginning of processing and not
  3450.     bother setting them each time the POM file is executed (i.e. each time an
  3451.     input line is read).
  3452.     
  3453.     If you are working with multiple files (see "POM and Wildcards"), the
  3454.     PROLOGUE is run for each input file.  If you want to run some code for
  3455.     the first file only, you can set a "flag", as in this example:
  3456.     
  3457.     BEGIN firstfile = ""
  3458.       SET firstfile = "N"
  3459.       OUTEND |First file only
  3460.     ELSE
  3461.       OUTEND |Subsequent files
  3462.     END
  3463.     NEXTFILE
  3464.     
  3465.     If you run this POM file on several files at once, using wildcards, the
  3466.     first line of the output file will contain the words "First file only",
  3467.  
  3468.                                                                              54
  3469.     since the variable "firstfile" has not yet been assigned a value.  On
  3470.     subsequent files, the variable will have the value "N", so the following
  3471.     lines of the output file will read "Subsequent files".
  3472.     
  3473.                                 --------------------
  3474.                                 The EPILOGUE Command
  3475.                                 --------------------
  3476.     
  3477.     FORMAT:        The format for EPILOGUE (used with the END command) is:
  3478.     
  3479.                    EPILOGUE
  3480.                    :
  3481.                    Dependant code
  3482.                    :
  3483.                    END
  3484.     
  3485.     PURPOSE:       EPILOGUE defines dependant code which is run after the last
  3486.                    line of the input file is read and the POM file is executed
  3487.                    to process it.  In other words, once all the input data is
  3488.                    finished, the POM file runs one last time -- but only the
  3489.                    code in the EPILOGUE section.
  3490.     
  3491.     SEE ALSO:      "The Prologue Command"
  3492.     
  3493.     You can use EPILOGUE to output final results.  Let's say your input file
  3494.     looks like this:
  3495.     
  3496.     DESCRIPTION      UNITS SOLD    UNIT PRICE
  3497.     Wildebeest food         325    $     9.99
  3498.     Horse cologne            13    $     3.25
  3499.     Moose alarm             210    $     5.95
  3500.     :                :        :     :       :    (Column positions)
  3501.     1               18       27    33      41
  3502.     
  3503.     You can find out the total number of units sold (of all types) with the
  3504.     following POM file:
  3505.     
  3506.     IGNORE $FLINE[1 7] = "DESCRIP"
  3507.     CALC   units = units "+" $FLINE[18 27]
  3508.     EPILOGUE
  3509.       OUTEND |Total units sold = {units}
  3510.     END
  3511.     
  3512.     This POM file adds up the number of units sold.  The only output is the
  3513.     single line generated by the OUTEND in the EPILOGUE.
  3514.     
  3515.     If you are processing multiple files (see "POM and Wildcards"), the
  3516.     EPILOGUE is run after each input file is finished.
  3517.     
  3518.     
  3519.     
  3520.  
  3521.  
  3522.  
  3523.                                                                              55
  3524.     ============================================================================
  3525.                                  VARIABLE MODIFIERS
  3526.     ============================================================================
  3527.     
  3528.                                   ----------------
  3529.                                   The TRIM Command
  3530.                                   ----------------
  3531.     
  3532.     FORMAT:        TRIM var1 value1 value2
  3533.     
  3534.     PURPOSE:       TRIM removes the character in value2 from var1.
  3535.     
  3536.     PARAMETERS:    var1   is the variable being set
  3537.                    value1 is "A" = All; "B" = Both ends;
  3538.                              "L" = Left side only; "R" = Right side only;
  3539.                              "M" = Multiples
  3540.                    value2 is the character to be removed.
  3541.     
  3542.     ALTERNATIVES:  The SET, CHANGE and REMAP commands
  3543.     
  3544.     The TRIM command gets rid of unwanted characters in a variable.  It is
  3545.     typically used to remove blanks from either side of text, or leading zeros
  3546.     from numeric data.
  3547.     
  3548.     For example, to remove commas and the leading dollar sign from a number:
  3549.     
  3550.     SET  PRICE = $FLINE[20 26]      <-- Get the variable from the input file
  3551.     TRIM PRICE "A" ","              <-- Trim All
  3552.     TRIM PRICE "L" "$"              <-- Trim Left
  3553.     
  3554.     Here is how it works:
  3555.     
  3556.     If the input contains the string:   "$25,783"
  3557.     The first TRIM changes it to:       "$25783"
  3558.     The second TRIM changes it to:      "25783"
  3559.     
  3560.     You can also squeeze out multiple occurrences of a given character.  For
  3561.     example, to remove multiple spaces from a variable named xyz, use this
  3562.     command:
  3563.     
  3564.     TRIM xyz "M" " "
  3565.     
  3566.     If xyz has the value "  A  B C  ", the command shown above changes it to
  3567.     " A B C ".  You can then get rid of the spaces at both ends with this
  3568.     command:
  3569.     
  3570.     TRIM xyz "B" " "
  3571.     
  3572.     This changes the xyz variable to "A B C".
  3573.     
  3574.  
  3575.  
  3576.  
  3577.  
  3578.                                                                              56
  3579.                                   ---------------
  3580.                                   The PAD Command
  3581.                                   ---------------
  3582.     
  3583.     FORMAT:        PAD var1 value1 value2 value3
  3584.                        :    :       :     :
  3585.     MEANING:       Variable Control Char  Number
  3586.     
  3587.     PURPOSE:       PAD makes var1 a specified length, padded with a
  3588.                    specified character.
  3589.     
  3590.     PARAMETERS:    var1   is the variable being set
  3591.                    value1 is "L", "R", or "C" (Left, Right or Center)
  3592.                    value2 is the character used to pad the string
  3593.                    value3 is the desired string length
  3594.     
  3595.     NUMERICS:      Tabs, spaces and commas are stripped from value3
  3596.     
  3597.     ALTERNATIVES:  The CHANGE command
  3598.     
  3599.     Here is an example of the PAD command.  If the variable ABC is already set
  3600.     to "1234" ...
  3601.     
  3602.     PAD ABC "L" "0" "7"   left-pads it 7 characters wide with zeros ("0001234")
  3603.     PAD ABC "R" " " "5"   right-pads it 5 characters wide with spaces ("1234 ")
  3604.     PAD ABC "C" "*" "8"   centers it, 8 wide, with asterisks ("**1234**")
  3605.     
  3606.     If the length is less than the length of the string, it is unchanged.  For
  3607.     example, if you set variable XYZ to "PINNACLE", then
  3608.     
  3609.     PAD XYZ "R" " " "3"
  3610.     
  3611.     leaves the string as-is ("PINNACLE").
  3612.     
  3613.     Thus, PAD can not be used to shorten a string.  If it is your intention to
  3614.     make XYZ 3 letters long, you can use the SET command:
  3615.     
  3616.     SET XYZ = XYZ[1 3]
  3617.     
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.  
  3632.  
  3633.                                                                              57
  3634.                                  ------------------
  3635.                                  The CHANGE Command
  3636.                                  ------------------
  3637.     
  3638.     FORMAT:        CHANGE var1 value1 value2
  3639.     
  3640.     PURPOSE:       The CHANGE command replaces ALL occurrences of value1
  3641.                    with value2.
  3642.     
  3643.     ALTERNATIVES:  The TRIM command.  (The CHANGE command is more powerful than
  3644.                    TRIM, but is not as efficient).
  3645.     
  3646.     Here is an example of the CHANGE command in action:
  3647.     
  3648.     SET    DATE = $FLINE[31 38]
  3649.     CHANGE DATE "/" "--"
  3650.     
  3651.     If the SET command assigns DATE the value:    "93/10/15"
  3652.     Then the CHANGE command converts it to:       "93--10--15"
  3653.     
  3654.                                 -------------------
  3655.                                 The CVTCASE Command
  3656.                                 -------------------
  3657.     
  3658.     FORMAT:        CVTCASE  var1 value1 [value2]
  3659.     
  3660.     PURPOSE:       CVTCASE converts a value to uppercase or lowercase.
  3661.     
  3662.     PARAMETERS:    var1   is the variable being set
  3663.                    value1 is the value being converted
  3664.                    value2 is the optional control setting
  3665.     
  3666.     DEFAULTS:      value2 = "UI"
  3667.     
  3668.     ALTERNATIVES:  The PROPER or REMAP commands; $FLUPC
  3669.     
  3670.     CVTCASE converts value1 to uppercase or lowercase and places the result in
  3671.     var1.  Here are some examples:
  3672.     
  3673.          COMMAND                      DESCRIPTION
  3674.          ---------------------------  --------------------------------
  3675.          CVTCASE xyz "Test Case" "U"  Sets variable xyz to "TEST CASE"
  3676.          CVTCASE xyz "Test Case" "L"  Sets variable xyz to "test case"
  3677.          CVTCASE xyz "Test Case"      Sets variable xyz to "TEST CASE"
  3678.     
  3679.     In the last example, the optional control parameter (value2) was omitted.
  3680.     In such case, CVTCASE will convert the value to uppercase.
  3681.     
  3682.  
  3683.  
  3684.  
  3685.  
  3686.  
  3687.  
  3688.                                                                              58
  3689.     ----------------
  3690.     Control Settings
  3691.     ----------------
  3692.     
  3693.     The control setting (value2) can be one or two characters long, or it can
  3694.     be omitted (in which case it is assumed to be "UI").  Here are the
  3695.     available settings for value2:
  3696.     
  3697.                     SETTING  CONVERT TO  CHARACTER SET
  3698.                     -------  ----------  ------------------
  3699.                     "L"      Lowercase   IBM Extended ASCII
  3700.                     "LI"     Lowercase   IBM Extended ASCII
  3701.                     "L7"     Lowercase   7-bit ASCII
  3702.                     "U"      Uppercase   IBM Extended ASCII
  3703.                     "UI"     Uppercase   IBM Extended ASCII
  3704.                     "U7"     Uppercase   7-bit ASCII
  3705.     
  3706.     The IBM Extended ASCII character set defines diacritical (accented)
  3707.     characters such as "U Umlaut" and "C Cedille"; these are located in the
  3708.     ASCII table above value 127.  It is the standard character set used by
  3709.     MS-DOS and PC-DOS.
  3710.     
  3711.     The 7-bit ASCII character set is concerned only with the characters in the
  3712.     original definition of ASCII (American Standard Code for Information
  3713.     Interchange), which does not support diacritical characters.  As such,
  3714.     uppercasing and lowercasing affect only alphabetic characters ("A" to "Z",
  3715.     and "a" to "z").  This character set is used by many mini-computers, and
  3716.     is the standard character set of the Unix operating system.
  3717.     
  3718.     The eighth bit is not ignored if you use CVTCASE with the 7-bit ASCII
  3719.     character set.  If you wish to set the eighth bit to zero (perhaps because
  3720.     it is a parity bit), you should use the REMAP command.
  3721.     
  3722.  
  3723.  
  3724.  
  3725.  
  3726.  
  3727.  
  3728.  
  3729.  
  3730.  
  3731.  
  3732.  
  3733.  
  3734.  
  3735.  
  3736.  
  3737.  
  3738.  
  3739.  
  3740.  
  3741.  
  3742.  
  3743.                                                                              59
  3744.                                  ------------------
  3745.                                  The PROPER Command
  3746.                                  ------------------
  3747.     
  3748.     FORMAT:        PROPER var1 [value1 [value2]]
  3749.     
  3750.     PURPOSE:       The PROPER command converts uppercase text (LIKE THIS) to
  3751.                    mixed-case text (Like This).
  3752.     
  3753.     PARAMETERS:    var1   is the variable being set
  3754.                    value1 is the methods setting
  3755.                    value2 is the name of the Properization Exception File
  3756.     
  3757.     DEFAULTS:      value1 = "IW"
  3758.     
  3759.     ALTERNATIVES:  The CHANGE command; $FLUPC (uppercase version of $FLINE)
  3760.     
  3761.     The PROPER command is useful when you have a list of names of people and
  3762.     addresses.  You can also use PROPER to change text that has been typed in
  3763.     uppercase into normal text, with capital letters at the beginning of
  3764.     sentences.
  3765.     
  3766.     The simplest way to convert a variable is as follows:
  3767.     
  3768.     PROPER CustName
  3769.     
  3770.     If CustName contains "JOHN SMITH", it will be changed to "John Smith".
  3771.     
  3772.     The conversion routine is fairly intelligent.  For example, if it is
  3773.     converting the words "JAGUAR XJS", it can tell that XJS is not a word
  3774.     (since it does not contain any vowels) and so the end result will
  3775.     be "Jaguar XJS".  Other "strange-looking" items such as serial numbers
  3776.     can often be recognized by the PROPER command, and left untouched.
  3777.     
  3778.     Nevertheless, it is impossible to handle all situations, so the PROPER
  3779.     command supports a "Properization Exceptions File" (known as a PEF file).
  3780.     A PEF file lists unusual combinations of letters (typically abbreviations,
  3781.     such as Dr.).  The Parse-O-Matic package includes a file named GENERIC.PEF,
  3782.     which you may find helpful.  You can view it with the SEE program provided
  3783.     with Parse-O-Matic.
  3784.     
  3785.     A PEF file is prepared with a text editor and contains one "exception" per
  3786.     line.  Null or blank lines, or lines that start with a semicolon, are
  3787.     ignored.  The longest word that can be specified is 255 characters.
  3788.     Spaces are permitted, but leading and trailing spaces and tabs are ignored.
  3789.     
  3790.     To use the PEF file in your PROPER command, place the file name after the
  3791.     variable name and method setting.  For example:
  3792.     
  3793.     PROPER CustName "W" "GENERIC.PEF"
  3794.     
  3795.     The "W" is the method setting (explained later).  "GENERIC.PEF" is the name
  3796.     of the PEF file.  When Parse-O-Matic looks for the PEF file, it looks for
  3797.  
  3798.                                                                              60
  3799.     it in the current directory unless an explicit path is specified, then
  3800.     searches elsewhere, if necessary.  (For details, see the section entitled
  3801.     "How Parse-O-Matic Searches for a File".)
  3802.     
  3803.     If it can not find it there, it looks in the
  3804.     directory where POM.EXE is located.  You can, if you wish, specify a
  3805.     complete path to the file, as in this example:
  3806.     
  3807.     PROPER Address "W" "C:\MYFILES\MYPEF.XYZ"
  3808.     
  3809.     If you don't need an exceptions file, you should not use it, since it slows
  3810.     down processing somewhat.  Needless to say, the more items you have in the
  3811.     PEF file, the more it slows down processing.
  3812.     
  3813.     The method setting allows you to specify what PROPER does.  There are
  3814.     several kinds of controls, as follows:
  3815.     
  3816.           METHOD   DESCRIPTION
  3817.           ------   -----------
  3818.             I      Intelligent determination of non-words
  3819.             S      Upcase the first character of each sentence
  3820.             U      Upcase the first alphanumeric character of the line
  3821.             W      Upcase the first letter of each word
  3822.     
  3823.     The default method setting is "IW", so if you omit the method setting, or
  3824.     specify a null setting (e.g. PROPER CustName "" "XYZ.PEF"), PROPER will
  3825.     upcase non-words, and the first letter of each word.
  3826.     
  3827.     NOTE:  If you specify a PEF file, you must also specify a method setting,
  3828.     even if it is null.  The line PROPER x "GENERIC.PEF" would not be understood
  3829.     by Parse-O-Matic.  The correct format would be:  PROPER x "" "GENERIC.PEF"
  3830.     
  3831.     The examples provided with Parse-O-Matic demonstrate some ways you can use
  3832.     the PROPER command.  To see the examples, enter START at the DOS prompt,
  3833.     or run START.BAT from Windows or OS/2, then select TUTORIAL.
  3834.     
  3835.  
  3836.  
  3837.  
  3838.  
  3839.  
  3840.  
  3841.  
  3842.  
  3843.  
  3844.  
  3845.  
  3846.  
  3847.  
  3848.  
  3849.  
  3850.  
  3851.  
  3852.  
  3853.                                                                              61
  3854.                                  ------------------
  3855.                                  The INSERT Command
  3856.                                  ------------------
  3857.     
  3858.     FORMAT:        INSERT var1 value1 value2
  3859.     
  3860.     PURPOSE:       The INSERT command inserts text on the left or right of
  3861.                    var1, or at a "found text" position.
  3862.     
  3863.     PARAMETERS:    var1   is the variable being set
  3864.                    value1 is "L" or "R" (Left or Right) or a find-string
  3865.                           (e.g.  "<HELLO")
  3866.                    value2 is the value to be inserted
  3867.     
  3868.     ALTERNATIVES:  The APPEND and CHANGE commands
  3869.     
  3870.     For example, if the variable ABC is set to "Parse-O-Matic", then
  3871.     
  3872.     INSERT ABC "L" "Register "    sets ABC to "Register Parse-O-Matic"
  3873.     INSERT ABC "R" " is super"    sets ABC to "Parse-O-Matic is super"
  3874.     
  3875.     You can use a find-string to insert text either before or after the first
  3876.     occurrence of the text you specify.  For example, if the variable xyz is
  3877.     set to "One a day", then
  3878.     
  3879.     INSERT xyz "<e"    "c"        sets xyz to "Once a day"
  3880.     INSERT xyz ">One " "hour "    sets xyz to "One hour a day"
  3881.     
  3882.     The < prefix means "insert value1 before the found text".  The > prefix
  3883.     means "insert value1 after the found text".
  3884.     
  3885.     If the find-string is not found, nothing is done.
  3886.     
  3887.     NOTE:  Prior to version 3.40 of Parse-O-Matic, the "insert before" opera-
  3888.            tion was denoted by the @ prefix rather than the < prefix.  This
  3889.            still works, so you do not have to change your POM files.
  3890.     
  3891.  
  3892.  
  3893.  
  3894.  
  3895.  
  3896.  
  3897.  
  3898.  
  3899.  
  3900.  
  3901.  
  3902.  
  3903.  
  3904.  
  3905.  
  3906.  
  3907.  
  3908.                                                                              62
  3909.                                  ------------------
  3910.                                  The APPEND Command
  3911.                                  ------------------
  3912.     
  3913.     FORMAT:        APPEND var1 value1 value2 [value3 [value4]]
  3914.     
  3915.     PURPOSE:       The APPEND command concatenates (adds together) two or more
  3916.                    values and places the result in var1.
  3917.     
  3918.     NOTES:         No variable can hold more than 255 characters.
  3919.     
  3920.     ALTERNATIVES:  The INSERT command
  3921.     
  3922.     Here is an example of the APPEND command:
  3923.     
  3924.     APPEND xyz "AB" "CD" "EF" "GHIJ"
  3925.     
  3926.     This command sets the variable xyz to "ABCDEFGHIJ".
  3927.     
  3928.     The third and fourth values (value3 and value4 in the FORMAT shown above)
  3929.     are optional.  Thus, you can use APPEND with only two values.  For example:
  3930.     
  3931.     SET    x1 = "AB"
  3932.     SET    x2 = "CD"
  3933.     APPEND x3 x1 x2
  3934.     
  3935.     This sets the variable x3 to "ABCD".  You can concatenate a maximum of four
  3936.     values with a single APPEND command.  If you require additional concaten-
  3937.     ations, you can use more APPEND commands:
  3938.     
  3939.     APPEND myvar "ABC" "DEF" "GHI" "JKL"
  3940.     APPEND myvar myvar "MNO" "PQR"
  3941.     
  3942.     The first line sets the variable myvar to "ABCDEFGHIJKL".  The second line
  3943.     set myvar to its previous value, plus "MNOPQR", so that its final value is
  3944.     "ABCDEFGHIJKLMNOPQR".
  3945.     
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.  
  3957.  
  3958.  
  3959.  
  3960.  
  3961.  
  3962.  
  3963.                                                                              63
  3964.                                 -------------------
  3965.                                 The OVERLAY Command
  3966.                                 -------------------
  3967.     
  3968.     FORMAT:        OVERLAY var1 value1 value2
  3969.     
  3970.     PURPOSE:       The OVERLAY command overwrites a portion of a variable with
  3971.                    a value, at the specified position.  The length of the
  3972.                    variable is padded with spaces if necessary.
  3973.     
  3974.     PARAMETERS:    var1   is the variable to be overwritten
  3975.                    value1 is the data which will be placed into var1
  3976.                    value2 is the position, in var1, where value1 will be placed
  3977.     
  3978.     NOTES:         No variable can hold more than 255 characters.
  3979.     
  3980.     NUMERICS:      Tabs, spaces and commas are stripped from value2
  3981.                    value2 must be between "1" and "255"
  3982.     
  3983.     SEE ALSO:      "The Append Command" and "The Insert Command"
  3984.     
  3985.     The OVERLAY command lets you replace part of a variable, starting at a
  3986.     particular position.  Here is an example:
  3987.     
  3988.     SET      x = "ABCDEFG"
  3989.     SET      y = "pom"
  3990.     OVERLAY  x y "4"
  3991.     
  3992.     This will change the x variable so it contains "ABCpomG", since it places
  3993.     the "pom" at position "4".
  3994.     
  3995.     If value2 is greater than the length of var1, var1 is padded with spaces to
  3996.     allow value2 to be placed at the specified position.  For example:
  3997.     
  3998.     SET      x = "ABCDEFG"
  3999.     SET      y = "pom"
  4000.     OVERLAY  x y "10"
  4001.     
  4002.     This will change the x variable to "ABCDEFG  pom".  Since var1 was less than
  4003.     10 characters, it had to be extended to allow the "pom" to start in position
  4004.     "10".
  4005.     
  4006.     Since no variable can be more than 255 characters, OVERLAY will truncate the
  4007.     result if it extends beyond that:
  4008.     
  4009.     SET      x = "ABCDEFG"
  4010.     SET      y = "pom"
  4011.     OVERLAY  x y "254"
  4012.     
  4013.     The x variable will be 255 characters long (starting with "ABCDEFG",
  4014.     followed by many spaces) and end with "po", since the "p" is in position
  4015.     "254" and the "o" is in the last legal position (i.e. "255").
  4016.     
  4017.  
  4018.                                                                              64
  4019.     Here are some additional examples:
  4020.     
  4021.     SET      x = ""        <-- Set x to a null (empty) string
  4022.     OVERLAY  x "ABC" "1"   <-- Set x to "ABC" (i.e. the "A" is at position "1")
  4023.     OVERLAY  x "DEF" "4"   <-- Change x from "ABC" to "ABCDEF"
  4024.     OVERLAY  x "IJ"  "9"   <-- Change x to "ABCDEF  IJ"
  4025.     OVERLAY  x "GH"  "7"   <-- Change x to "ABCDEFGHIJ"
  4026.     
  4027.     -------------
  4028.     Simple Arrays
  4029.     -------------
  4030.     
  4031.     You can use OVERLAY to perform some simple array processing, provided the
  4032.     total length of the data items does not exceed 255 characters.  For example,
  4033.     you could store 25 items of up to 10 characters each in a 250-character
  4034.     variable. Here is a helpful subroutine (see "The Code Command") for this
  4035.     kind of operation:
  4036.     
  4037.     CODE     "Calc Array Indexes"
  4038.       SET      ItemSize  = "10"
  4039.       CALC     IndexStart = Index- "*" ItemSize
  4040.       CALC     IndexEnd   = IndexStart "+" ItemSize
  4041.       SET      IndexStart = IndexStart+
  4042.     END
  4043.     
  4044.     This will provide pointers for an array of 25 items of up to 10 characters
  4045.     each, with indexes of 1 to 10. You can use this information with both the
  4046.     OVERLAY and COPY commands.  You could extract the 15th item as follows:
  4047.     
  4048.     SET      Index = "15"
  4049.     CALL     "Calc Array Indexes"
  4050.     COPY     x MyArray IndexStart IndexEnd
  4051.     
  4052.     For a more sophisticated and flexible method of handling arrays, see "Array
  4053.     Variables".
  4054.     
  4055.  
  4056.  
  4057.  
  4058.  
  4059.  
  4060.  
  4061.  
  4062.  
  4063.  
  4064.  
  4065.  
  4066.  
  4067.  
  4068.  
  4069.  
  4070.  
  4071.  
  4072.  
  4073.                                                                              65
  4074.                                 -------------------
  4075.                                 The MAPFILE Command
  4076.                                 -------------------
  4077.     
  4078.     FORMAT:        value1 value2 [value3]
  4079.     
  4080.     PURPOSE:       MAPFILE reads a file containing data for the REMAP command
  4081.     
  4082.     PARAMETERS:    value1 is the name of the map file
  4083.                    value2 is the map name, used by the REMAP command
  4084.                    value3 is the control settings (AnyCase/MatchCase/Transpose)
  4085.     
  4086.     DEFAULTS:      value3 = "MATCHCASE"
  4087.     
  4088.     NOTES:         The maximum length of a map name is 12 characters
  4089.     
  4090.     SEE ALSO:      "The Remap Command", "How Parse-O-Matic Searches for a File"
  4091.     
  4092.     The MAPFILE command reads in a file which contains data for the REMAP
  4093.     command, and assigns a name to the collection of data so the REMAP command
  4094.     can refer to it.
  4095.     
  4096.     -------------------
  4097.     What is a Map File?
  4098.     -------------------
  4099.     
  4100.     A map file is an ordinary text file; you can create or edit the file with a
  4101.     standard text editor, or a word-processor in "generic text" mode. Map files
  4102.     are usually given the .MPF extension.
  4103.     
  4104.     A map file contains a list of "mappings".  Here are some other words with
  4105.     approximately the same meaning as "mapping":
  4106.     
  4107.       Translation   Correlation   Substitution   Equivalence   Replacement
  4108.     
  4109.     In other words, the map file contains a list of data items that should be
  4110.     replaced by other data items.
  4111.     
  4112.     ----------------
  4113.     Sample Map Files
  4114.     ----------------
  4115.     
  4116.     The following map files are included in the standard Parse-O-Matic package:
  4117.     
  4118.     FILE NAME     DESCRIPTION
  4119.     ------------  ----------------------------------------------------------
  4120.     BIN2CHAR.MPF  Converts binary data into printable characters and periods
  4121.     BIN2CODE.MPF  Converts binary data into hex codes (e.g. 3F 2C A3)
  4122.     ASC2EBCD.MPF  Converts ASCII data to EBCDIC and vice-versa
  4123.     
  4124.  
  4125.  
  4126.  
  4127.  
  4128.                                                                              66
  4129.     ---------------
  4130.     Map File Format
  4131.     ---------------
  4132.     
  4133.     The map file contains one mapping per line.  Each mapping consists of two
  4134.     Parse-O-Matic literals, separated by one or more spaces or tabs. The first
  4135.     value is the "find" column, while the second value is the "replace" column.
  4136.     Here are some examples:
  4137.     
  4138.     "123"  "LOS ANGELES"      <-- Both values are "literal text strings"
  4139.     $39    "9"                <-- A hex code and a literal text string
  4140.     #48    "Zero"             <-- A decimal code and a literal text string
  4141.     $FF$30 #00#00             <-- Hex and decimal literals
  4142.     
  4143.     These columns are lined up for clarity; there is no need to start in a
  4144.     particular column.  Any leading or trailing spaces are removed from a
  4145.     line, and any number of spaces or tabs can appear between the columns.
  4146.     
  4147.     The following line is NOT valid:
  4148.     
  4149.     123    LOS ANGELES
  4150.     
  4151.     The line must use text, hex or decimal literals (e.g. "text", $FF, #FF).
  4152.     
  4153.     Null or blank lines, or lines that start with a semicolon, are ignored.
  4154.     The longest line that can be specified is 255 characters.  The longest
  4155.     value that can be specified is 80 characters (after translation, if it
  4156.     is in hex or decimal mode).
  4157.     
  4158.     ------------
  4159.     Search Order
  4160.     ------------
  4161.     
  4162.     The REMAP command performs substitutions in the order that they appear in
  4163.     the map file.  In most cases, the longer "find" strings should appear
  4164.     first.  For example, let us say you create a map file named FORWARD.MPF,
  4165.     which looks like this:
  4166.     
  4167.     "123"   "in Los Angeles"
  4168.     "12"    "in Montreal"
  4169.     "1"     "in Town of Mount Royal"
  4170.     "2"     "in Podunk"
  4171.     
  4172.     Now let's say you run the following POM file, named FORWARD.POM:
  4173.     
  4174.     MAPFILE "FORWARD"
  4175.     SET     comment = "Forward the memo to office 123"
  4176.     REMAP   comment
  4177.     OUTEND  |{comment}
  4178.     
  4179.     This will produce the following output:
  4180.     
  4181.  
  4182.  
  4183.                                                                              67
  4184.     Forward the memo to office in Los Angeles
  4185.     
  4186.     This happens because the string "123" is replaced by the string "in Los
  4187.     Angeles".
  4188.     
  4189.     If the order of the lines in FORWARD.MPF are reversed, FORWARD.POM will
  4190.     produce the following output:
  4191.     
  4192.     Forward memo to Office in Town of Mount RoyalinPodunk3
  4193.     
  4194.     This happens because the "1" is found (and replaced) first, followed by the
  4195.     "2".  Since there is no "3" in FORWARD.MPF, it is left alone.
  4196.     
  4197.     Parse-O-Matic does NOT enforce the principle of "progressively shorter
  4198.     'find' strings".  If you are processing a lot of data, you can improve
  4199.     processing speed slightly by placing a short, frequently-used "find" string
  4200.     near the top of the list.  As long as it is not a sub-string of (i.e.
  4201.     contained within) one of the following strings, it will not cause any
  4202.     problems.
  4203.     
  4204.     -------------
  4205.     Case Matching
  4206.     -------------
  4207.     
  4208.     You can set value3 to "AnyCase" or "MatchCase" (the default).
  4209.     
  4210.     ANYCASE:    The find string need not match in case ("John" = "JOHN")
  4211.     MATCHCASE:  The find string must match ("John" does not match "JOHN")
  4212.     
  4213.     Processing is faster if you use the default setting (MatchCase).
  4214.     
  4215.     ---------------
  4216.     Reverse Mapping
  4217.     ---------------
  4218.     
  4219.     If you want the mapping process to work "backwards", you can use the
  4220.     "Transpose" control setting in value3.  For example:
  4221.     
  4222.     MAPFILE "MYFILE.MPF" "MYFILE" "AnyCase Transpose"
  4223.     
  4224.     This reverses the mapping process:  the "find" column is treated like the
  4225.     "replace with" column, and vice-versa.
  4226.     
  4227.     The standard Parse-O-Matic package contains a map file (ASC2EBCD.MPF) which
  4228.     will translate ASCII files into EBCDIC files -- and vice-versa.
  4229.     
  4230.     NOTE:  EBCDIC is a character representation used on certain large mainframe
  4231.            computers.  Both ASCII and EBCDIC characters are eight bits long,
  4232.            but EBCDIC uses different bit patterns for most characters.
  4233.     
  4234.     Since both the "find" and "replace with" columns in ASC2EBCD.MPF are only
  4235.     one character wide, and since there is no duplication within either column,
  4236.     the translation process is perfectly reversible.  For example:
  4237.  
  4238.                                                                              68
  4239.     PROLOGUE
  4240.       CHOP     1 20                                <-- Read 20 bytes at a time
  4241.       MAPFILE  "ASC2EBCD.MPF" "EBCDIC"             <-+
  4242.       MAPFILE  "ASC2EBCD.MPF" "ASCII" "TRANSPOSE"    | Set up maps
  4243.       MAPFILE  "BIN2CODE.MPF" "CODE"               <-+
  4244.     END
  4245.     SET      x = $FLINE                            <-+
  4246.     REMAP    x "CODE"                                | Display original text in
  4247.     OUTEND   |[ORIGINAL] [{$FLINE}]                  | normal & hex-coded form
  4248.     OUTEND   |[ORIGINAL] [{x}]                     <-+
  4249.     REMAP    $FLINE "EBCDIC"                       <-+
  4250.     SET      x = $FLINE                              | Convert to EBCDIC and
  4251.     REMAP    x "CODE"                                | display in coded form
  4252.     OUTEND   |[EBCDIC  ] [{x}]                     <-+
  4253.     REMAP    $FLINE "ASCII"                        <-+
  4254.     SET      x = $FLINE                              | Convert EBCDIC back to
  4255.     REMAP    x "CODE"                                | ASCII; display hex code
  4256.     OUTEND   |[ASCII   ] [{x}]                     <-+
  4257.     OUTEND   |                                     <-- Output a separator line
  4258.     
  4259.     You can run this POM file against any file, then view the output file.  You
  4260.     will see how the original text is converted into EBCDIC and then the EBCDIC
  4261.     is converted back to ASCII.  (Most of the data in the output file is
  4262.     represented in "hex dump" format, since your computer is not designed to
  4263.     display EBCDIC.)
  4264.     
  4265.     TRANSPOSE will often let you use a single map file instead of two, but
  4266.     before using this technique you should carefully consider how mapping will
  4267.     take place (see "Irreversible Mapping", below).
  4268.     
  4269.     --------------------
  4270.     Irreversible Mapping
  4271.     --------------------
  4272.     
  4273.     Consider the following POM file:
  4274.     
  4275.     MAPFILE "MYMAP.MPF" "XYZ"
  4276.     MAPFILE "MYMAP.MPF" "ZYX" "TRANSPOSE"
  4277.     REMAP   $FLINE "XYZ"
  4278.     REMAP   $FLINE "ZYX"
  4279.     OUTEND  |{$FLINE}
  4280.     
  4281.     In many cases, this is equivalent to the following one-line POM file:
  4282.     
  4283.     OUTEND  |{$FLINE}
  4284.     
  4285.     because the first REMAP changes $FLINE one way, and the second REMAP
  4286.     changes it back.
  4287.     
  4288.  
  4289.  
  4290.  
  4291.  
  4292.  
  4293.                                                                              69
  4294.     This is not true in ALL cases, however.  In some circumstances a REMAP is
  4295.     not reversible.  Consider the following map file:
  4296.     
  4297.     "XYZ"  "CAB"
  4298.     "ABC"  "C"
  4299.     "DEF"  "ABC"
  4300.     
  4301.     Now consider the following sequence of events.  (The * and # characters
  4302.     show what gets replaced in each step.)
  4303.     
  4304.                  Original string   . . . . . . . . .   ABCDEF
  4305.                                                        ***###
  4306.     
  4307.                                                        *###
  4308.                  Remap produces this result  . . . .   CABC
  4309.                                                        ***
  4310.     
  4311.                                                        ***
  4312.                  Transposed remap of result  . . . .   XYZC
  4313.     
  4314.     If you follow the steps of the substitutions, you will see where the
  4315.     confusion arises.  As a general rule, simple substitutions (with no
  4316.     duplications in whole or in part) are reversible, but if you have any
  4317.     doubts, you can always take the safe route and use a separate map file
  4318.     for each direction.  (See "Search Order", above, for additional insight
  4319.     into this matter.)
  4320.     
  4321.     ------------------
  4322.     Memory Limitations
  4323.     ------------------
  4324.     
  4325.     The MAPFILE command reads the map data into RAM memory.  You will normally
  4326.     have sufficient memory for thousands of bytes worth of mappings. However,
  4327.     if you do not have enough memory to hold the data, Parse-O-Matic will
  4328.     display an error message, then terminate.  (See "Solving Memory Problems")
  4329.     
  4330.     To help you track memory usage, the MAPFILE command records memory status
  4331.     (bytes used and bytes left) in the processing log (see "Logging").
  4332.     
  4333.     -----------------------
  4334.     An Example of Remapping
  4335.     -----------------------
  4336.     
  4337.     The standard Parse-O-Matic package contains two sample map files:
  4338.     
  4339.     BIN2CODE.MPF maps single bytes to hex codes  (e.g. Hex $31 becomes "31 ")
  4340.     BIN2CHAR.MPF maps single bytes to either printable characters or periods
  4341.     
  4342.     You can view these files with the SEE program (included with Parse-O-Matic)
  4343.     or you can load them into a text editor program.
  4344.     
  4345.     Here is a POM file that uses the sample map files to create a hex dump of a
  4346.     binary file:
  4347.  
  4348.                                                                              70
  4349.     CHOP    1 16                  <-- Read the file 16 bytes at a time
  4350.     SETLEN  w $FLINE              <-- Get the actual number of bytes read
  4351.     BEGIN w <> "16"
  4352.       PAD $FLINE "R" #0 "16"      <-- If less than 16 bytes, pad with nulls
  4353.     END
  4354.     SET     x = $FLINE            <-- Make a copy of $FLINE
  4355.     SET     y = $FLINE            <-- Make a copy of $FLINE
  4356.     MAPFILE "BIN2CHAR" "CHAR"     <-- See Note
  4357.     MAPFILE "BIN2CODE.MPF" "CODE"
  4358.     REMAP   x "CHAR"              <-- Change the bytes to printable characters
  4359.     REMAP   y "CODE"              <-- Change the bytes to hex codes
  4360.     OUTEND  |x y                  <-- Output the line
  4361.     
  4362.     Note:  Since the file name (value1) does not have an extension,
  4363.            Parse-O-Matic will add the .MPF extension.  Thus, the actual file
  4364.            name Parse-O-Matic looks for is "BIN2CHAR.MPF".
  4365.     
  4366.                                  -----------------
  4367.                                  The REMAP Command
  4368.                                  -----------------
  4369.     
  4370.     FORMAT:        REMAP var1 value1
  4371.     
  4372.     PURPOSE:       REMAP transforms sub-strings into other strings
  4373.     
  4374.     PARAMETERS:    var1   is the variable being transformed
  4375.                    value1 is the map name (see "The MapFile Command")
  4376.     
  4377.     ALTERNATIVES:  The LOOKUP and CHANGE commands
  4378.     
  4379.     SEE ALSO:      "The MapFile Command"
  4380.     
  4381.     The REMAP command performs intensive substitutions on a variable.  It is
  4382.     equivalent to a large number of CHANGE commands, but has the following
  4383.     advantages:
  4384.     
  4385.     - It is faster than using a large number of CHANGEs
  4386.     - It does not expend your available values (see "Values")
  4387.     - It prevents multiple substitutions
  4388.     
  4389.     -------------------
  4390.     REMAP Versus CHANGE
  4391.     -------------------
  4392.     
  4393.     The "multiple substitution" issue is most important distinction between
  4394.     CHANGE and REMAP.  REMAP protects substituted text from being
  4395.     resubstituted.  Consider the following POM lines:
  4396.     
  4397.     SET    x = "cat dog mouse"
  4398.     CHANGE x "cat" "dog"
  4399.     CHANGE x "dog" "cat"
  4400.     
  4401.  
  4402.  
  4403.                                                                              71
  4404.     You might expect these lines to change x to "Dog Cat Mouse", but the actual
  4405.     result is "cat cat mouse".  The first CHANGE command sets the x variable to
  4406.     "dog dog mouse".  The next command changes the cats into dogs!
  4407.     
  4408.     You can avoid this problem by using intermediate substitutions or some such
  4409.     work-around, but this ends up complicating the POM file considerably.
  4410.     Moreover, this approach can be unwieldy if you have to perform a large
  4411.     number of substitutions.
  4412.     
  4413.     -----------
  4414.     Using REMAP
  4415.     -----------
  4416.     
  4417.     To accomplish the "cat/dog" substitution mentioned earlier, you can create
  4418.     a map file (named CATDOG.MPF) with a text editor.  It will look like this:
  4419.     
  4420.     "cat"  "dog"
  4421.     "dog"  "cat"
  4422.     
  4423.     Your POM file will then look like this:
  4424.     
  4425.     MAPFILE "CATDOG.MPF" "PETS"
  4426.     SET     x = "cat dog mouse"
  4427.     REMAP   x "PETS"
  4428.     
  4429.     This will change the x variable to "dog cat mouse".
  4430.     
  4431.     For another example of the REMAP command, see "The MapFile Command".
  4432.     
  4433.     
  4434.     
  4435.  
  4436.  
  4437.  
  4438.  
  4439.  
  4440.  
  4441.  
  4442.  
  4443.  
  4444.  
  4445.  
  4446.  
  4447.  
  4448.  
  4449.  
  4450.  
  4451.  
  4452.  
  4453.  
  4454.  
  4455.  
  4456.  
  4457.  
  4458.                                                                              72
  4459.     ============================================================================
  4460.                                  FREE-FORM COMMANDS
  4461.     ============================================================================
  4462.     
  4463.                             ----------------------------
  4464.                             What are Free-Form Commands?
  4465.                             ----------------------------
  4466.     
  4467.     The free-form commands are used for extracting information from an input
  4468.     line that does not have its data in precise columns.  Consider the
  4469.     following input file:
  4470.     
  4471.     Mouse     Gazelle   Mouse     Elephant
  4472.     Dog       Giraffe   Elk       Mongoose
  4473.     Monkey    Snake     Caribou   Trout
  4474.     |         |         |         |
  4475.     Column 1  Col 11    Col 21    Col 31
  4476.     
  4477.     Extracting data that is arranged in tidy columns is simple -- all you need
  4478.     is the SET command.  However, you will need a more powerful command if the
  4479.     data is "free-form", like this:
  4480.     
  4481.     Mouse,Gazelle,Mouse,Elephant
  4482.     Dog,Giraffe,Elk,Mongoose
  4483.     Monkey,Snake,Caribou,Trout
  4484.     
  4485.     The data is not arranged in tidy columns.  For tasks like this, you need
  4486.     the free-form commands.
  4487.     
  4488.  
  4489.  
  4490.  
  4491.  
  4492.  
  4493.  
  4494.  
  4495.  
  4496.  
  4497.  
  4498.  
  4499.  
  4500.  
  4501.  
  4502.  
  4503.  
  4504.  
  4505.  
  4506.  
  4507.  
  4508.  
  4509.  
  4510.  
  4511.  
  4512.  
  4513.                                                                              73
  4514.                                  -----------------
  4515.                                  The PARSE Command
  4516.                                  -----------------
  4517.     
  4518.     FORMAT:        PARSE var1 value1 value2 value3 [value4]
  4519.                          :    :      :      :       :
  4520.     MEANING:       Variable   Source From   To      Control
  4521.     
  4522.     PURPOSE:       PARSE sets var1 to the text (found in value1) between
  4523.                    text fragments specified by value2 and value3.
  4524.     
  4525.     PARAMETERS:    var1   is the variable being set
  4526.                    value1 is the source text being read
  4527.                    value2 specifies the starting position
  4528.                    value3 specifies the ending position
  4529.                    value4 is the optional control setting
  4530.     
  4531.     DEFAULTS:      value4 = "X"
  4532.     
  4533.     ALTERNATIVES:  The PEEL command, and COPY used with FINDPOSN
  4534.     
  4535.     Consider the following free-form data:
  4536.     
  4537.     Mouse,Gazelle,Mouse,Elephant
  4538.     Dog,Giraffe,Elk,Mongoose
  4539.     Monkey,Snake,Caribou,Trout
  4540.     
  4541.     The PARSE command lets you extract the "Nth" item.  For example, to extract
  4542.     the third item in each line in the free-form example above, you could use
  4543.     this command:
  4544.     
  4545.     PARSE  xyz  $FLINE  "2*,"  "3*,"
  4546.     
  4547.     This means "set the variable xyz by looking in $FLINE (the line just read
  4548.     from the input file) and taking everything between the second comma and the
  4549.     third comma".  For the three lines in the sample input file, the variable
  4550.     xyz is set to Mouse, then Elk, then Caribou.
  4551.     
  4552.     -------------
  4553.     Decapsulators
  4554.     -------------
  4555.     
  4556.     In the "From" specification in the previous example (i.e. the "2*," part
  4557.     of the command):
  4558.     
  4559.           2    means "the second occurrence"
  4560.           *    is a delimiter to mark the end of the occurrence number
  4561.           ,    is the text you are looking for
  4562.     
  4563.     Both the "From" and "To" specifications use this format.  Commands using
  4564.     this format are said to use "decapsulators", because you are extracting
  4565.     text that is encapsulated (i.e. surrounded) by other text.
  4566.     
  4567.  
  4568.                                                                              74
  4569.     Decapsulators may be used to find more than a single character.  The
  4570.     surrounding text can be up to 80 characters long.  Let's say the input file
  4571.     looks like this:
  4572.     
  4573.     Mouse%:Gazelle%:Mouse%:Elephant
  4574.     Dog%:Giraffe%:Elk%:Mongoose
  4575.     Monkey%:Snake%:Caribou%:Trout
  4576.     
  4577.     You can extract the third item in each line with this command:
  4578.     
  4579.            PARSE  xyz  $FLINE  "2*%:"  "3*%:"
  4580.                   ___  ______   _ ___    _ ___
  4581.                    |     |      |  |     |  |
  4582.      Variable to set     |      |  |     |  |
  4583.         The value to parse      |  |     |  "To" text being sought
  4584.          "From" occurrence number  |     "To" occurrence number
  4585.             "From" text being sought
  4586.     
  4587.     This command sets the variable xyz to Mouse, then Elk, then Caribou.
  4588.     
  4589.     ------------------
  4590.     Sample Application
  4591.     ------------------
  4592.     
  4593.     The PARSE command is particularly useful for extracting information from
  4594.     comma-delimited files.  Here is an example of a comma-delimited file:
  4595.     
  4596.     "Mouse","Gazelle","Mouse","Elephant"
  4597.     "Dog","Giraffe","Elk","Mongoose"
  4598.     "Monkey","Snake","Caribou","Trout"
  4599.     
  4600.     You can extract all the fields with this series of commands (note the use
  4601.     of doubled-up quotes to represent a single quotation mark -- see the
  4602.     section "Delimiters" for details):
  4603.     
  4604.     PARSE  field1  $FLINE  "1*"""  "2*"""
  4605.     PARSE  field2  $FLINE  "3*"""  "4*"""
  4606.     PARSE  field3  $FLINE  "5*"""  "6*"""
  4607.     PARSE  field4  $FLINE  "7*"""  "8*"""
  4608.     
  4609.     For the first line of the sample input file, field1 is set to Mouse, field2
  4610.     is set to Gazelle, and so on.
  4611.     
  4612.     ---------------------
  4613.     The Occurrence Number
  4614.     ---------------------
  4615.     
  4616.     The occurrence number must be between 1 and 255.  The following lines are
  4617.     not valid PARSE commands:
  4618.     
  4619.     PARSE  xyz  $FLINE  "0*,"  "1*,"    <-- "From" decapsulator invalid: uses 0
  4620.     PARSE  xyz  $FLINE  "1*,"  "256*,"  <-- "To" decapsulator invalid: uses 256
  4621.     
  4622.  
  4623.                                                                              75
  4624.     The occurrence number must always be followed by a "*" so you can search
  4625.     for a number.  Consider the following example (the meaning of which would
  4626.     be unclear without the "*" delimiter):
  4627.     
  4628.     PARSE  xyz  "XXX2YYY2ZZZ2"  "1*2"  "2*2"
  4629.     
  4630.     This sets xyz to the text occurring between the first "2" and the second
  4631.     "2".  In other words, xyz is set to "YYY".
  4632.     
  4633.     ---------------------------
  4634.     Finding the Last Occurrence
  4635.     ---------------------------
  4636.     
  4637.     A decapsulator can refer to "the LAST occurrence":
  4638.     
  4639.     PARSE  xyz  "AaaBAbbBAccB"  ">*A"  ">*B"
  4640.     
  4641.     In both decapsulators, the ">" symbol means "the last occurrence".  Thus,
  4642.     the command tells Parse-O-Matic, "Set the xyz variable to everything
  4643.     between the last A and the last B".  This sets the xyz variable to "cc".
  4644.     
  4645.     You can also use the "<" character to mean "the FIRST occurrence", although
  4646.     this is somewhat redundant, since the following commands are equivalent:
  4647.     
  4648.     PARSE  xyz  "AaaBAbbBAccB"  "<*A"  "<*B"
  4649.     PARSE  xyz  "AaaBAbbBAccB"  "1*A"  "1*B"
  4650.     PARSE  xyz  "AaaBAbbBAccB"  "A"  "B"
  4651.     
  4652.     All three commands set the xyz variable to "aa".
  4653.     
  4654.     ---------------------
  4655.     Unsuccessful Searches
  4656.     ---------------------
  4657.     
  4658.     If PARSE does not find the search text, the variable will be set to a null
  4659.     ("").  Here are two examples:
  4660.     
  4661.     PARSE  abc  "ABCDEFGHIJ"  "1*K"  "1*J"   <-- There is no "K"
  4662.     PARSE  abc  "ABCDEFGHIJ"  "1*A"  "1*X"   <-- There is no "X"
  4663.     
  4664.     If the "from" value is less than the "to" value, Parse-O-Matic will display
  4665.     an error message, then terminate.  For example:
  4666.     
  4667.     PARSE  abc  "ABCDEFGHIJ"  "1*J"  "1*A"   <-- "J" comes after "A"
  4668.     
  4669.     This kind of failure typically happens if the input data contains an odd
  4670.     arrangement of text that you had not foreseen.
  4671.     
  4672.  
  4673.  
  4674.  
  4675.  
  4676.  
  4677.  
  4678.                                                                              76
  4679.     -------------------
  4680.     The Control Setting
  4681.     -------------------
  4682.     
  4683.     The PARSE command has an optional "Control" parameter, which tells PARSE
  4684.     whether to include or exclude the surrounding text that was found.  By
  4685.     default (as shown in all of the preceding examples), the delimiting text
  4686.     is excluded.  However, if you want to include it, you can add "I" at the
  4687.     end of the PARSE command, as in this example:
  4688.     
  4689.     PARSE  xyz  "aXcaYcaZc"  "2*a"  "2*c"  "I"
  4690.     
  4691.     This tells Parse-O-Matic to give you everything between the second "a" and
  4692.     the second "c" -- including the "a" and "c".  In other words, this sets the
  4693.     variable xyz to "aYc".  You can also set the Control specification to "X"
  4694.     (meaning "exclude"), although since this is the default setting for PARSE,
  4695.     it really isn't necessary.  Here is an example:
  4696.     
  4697.     PARSE  xyz  "a1ca2ca3c"  "2*a"  "2*c"  "X"
  4698.     
  4699.     This sets the variable xyz to "2".
  4700.     
  4701.     ----------------------
  4702.     The Plain Decapsulator
  4703.     ----------------------
  4704.     
  4705.     The occurrence number is not always needed.  Either the "From" or "To"
  4706.     decapsulator can be represented as a plain string, as follows:
  4707.     
  4708.     PARSE $FLINE "ABC" "XYZ"
  4709.     
  4710.     This means:
  4711.     
  4712.     - Start at the first "ABC" found in the value being parsed
  4713.     - End with the first "XYZ" found in the value being parsed
  4714.     
  4715.     ---------------------
  4716.     The Null Decapsulator
  4717.     ---------------------
  4718.     
  4719.     Here is helpful variation of the "From" decapsulator:
  4720.     
  4721.     ""   means "Start from the first character in the value being parsed"
  4722.     
  4723.     A similar variation can be used with the "To" decapsulator:
  4724.     
  4725.     ""   means "End with the last character in the value being parsed"
  4726.     
  4727.     If you use the null ("") decapsulator for "From" or "To", the "found" value
  4728.     (the first character for "From", or the last character for "To") will
  4729.     always be included (see "Overlapping Decapsulators" for the single
  4730.     exception to this rule).  Here is an example:
  4731.     
  4732.  
  4733.                                                                              77
  4734.     PARSE  xyz  "ABCABCABC"  ""  "2*C"
  4735.     
  4736.     This sets the variable xyz to "ABCAB".  The "From" value (i.e. the first
  4737.     character) is NOT excluded.  However, when PARSE finds the "To" value (i.e.
  4738.     the second occurrence of the letter C) it IS excluded.  If you want to
  4739.     include the second "C", you should write the command this way:
  4740.     
  4741.     PARSE  xyz  "ABCABCABC"  ""  "2*C"  "I"
  4742.     
  4743.     The following two commands accomplish the same thing:
  4744.     
  4745.     PARSE  xyz  "ABCD"  ""  ""
  4746.     SET    xyz  "ABCD"
  4747.     
  4748.     They are equivalent because the PARSE command means "Set the variable xyz
  4749.     with everything between (and including) the first and last character".
  4750.     
  4751.     -----------------------------------
  4752.     Null Decapsulators Versus Exclusion
  4753.     -----------------------------------
  4754.     
  4755.     The reason that PARSE treats the null ("") decapsulator differently may
  4756.     not be immediately obvious, since the examples given here are very simple,
  4757.     and not representative of "real world" applications. However, in day-to-day
  4758.     usage, you will frequently find it helpful to be able to specify a command
  4759.     that says, "Give me everything from the beginning of the line to just
  4760.     before such-and-such".
  4761.     
  4762.     Here is a command that means "Give me everything from just after the dollar
  4763.     sign, to the end of the line":
  4764.     
  4765.     PARSE  xyz  "I'd like to have $250.00"  "1*$"  ""
  4766.     
  4767.     This sets xyz to "250.00".  If you want to include the dollar sign, write
  4768.     the command this way:
  4769.     
  4770.     PARSE  xyz  "I'd like to have $250.00"  "1*$"  ""  "I"
  4771.     
  4772.     -------------------------
  4773.     Overlapping Decapsulators
  4774.     -------------------------
  4775.     
  4776.     Earlier, it was mentioned that the text found by the null decapsulator is
  4777.     "always included" and is not affected by the "X" (Exclude) control.  There
  4778.     is one exception to this:  if the null decapsulator's "found text" is
  4779.     contained in the text found by the other decapsulator, it WILL be affected.
  4780.     For example:
  4781.     
  4782.     PARSE x "ABCDEFABCDEF" "" "1*AB" "X"
  4783.     
  4784.     This command tells Parse-O-Matic "give me everything between the first
  4785.     character and the first occurrence of AB".  Since the two items overlap
  4786.     (i.e. the first "AB" includes the first character), the first character
  4787.  
  4788.                                                                              78
  4789.     does indeed get excluded. As a result, the x variable is set to an empty
  4790.     string ("").
  4791.     
  4792.     Here is another example:
  4793.     
  4794.     PARSE x "ABCDEFABCDEF" ">*F" "" "X"
  4795.     
  4796.     This command tells Parse-O-Matic "give me everything between the last
  4797.     occurrence of F and the last character".  Both decapsulators refer to the
  4798.     same character (i.e. the final "F"), so it is excluded. As a result, the x
  4799.     variable is set to an empty string ("").
  4800.     
  4801.     NOTE:  In some circumstances, the FINDPOSN command is NOT affected by this
  4802.            exception.  It will do its best to make sense of your request if the
  4803.            decapsulators overlap, and one of them is a null decapsulator.  For
  4804.            details, see "The FindPosn Command".
  4805.     
  4806.     --------------------
  4807.     Parsing Empty Fields
  4808.     --------------------
  4809.     
  4810.     Consider the following command:
  4811.     
  4812.     PARSE x ",,,JOHN,SMITH" "2*," "3*,"
  4813.     
  4814.     There is nothing between the second and third comma, so the x variable
  4815.     is set to "" (an empty string).
  4816.     
  4817.     Now consider this command:
  4818.     
  4819.     PARSE x ",,,JOHN,SMITH" "" ","
  4820.     
  4821.     You are asking for everything from the first character to the first
  4822.     comma (which also happens to be the first character).  Obviously, there is
  4823.     nothing "between" the two characters, so the x variable would be set to ""
  4824.     (an empty string).
  4825.     
  4826.     -------------------
  4827.     Additional Examples
  4828.     -------------------
  4829.     
  4830.     For more examples of the PARSE command, see the demonstrations provided
  4831.     with Parse-O-Matic (type START at the DOS prompt, or run START.BAT from
  4832.     Windows or OS/2, then select TUTORIAL).
  4833.     
  4834.  
  4835.  
  4836.  
  4837.  
  4838.  
  4839.  
  4840.  
  4841.  
  4842.  
  4843.                                                                              79
  4844.                                 ----------------
  4845.                                 The PEEL Command
  4846.                                 ----------------
  4847.     
  4848.     FORMAT:        PEEL  var1 var2   value1 value2 [value3]
  4849.                          :    :      :      :       :
  4850.     MEANING:       Variable   Source From   To      Control
  4851.     
  4852.     PURPOSE:       The PEEL command works just like PARSE, but after setting
  4853.                    var1, it REMOVES the parsed value (including the delimiters)
  4854.                    from var2.
  4855.     
  4856.     PARAMETERS:    var1   is the variable being set
  4857.                    var2   is the source text being read
  4858.                    value1 specifies the starting position
  4859.                    value2 specifies the ending position
  4860.                    value3 is the optional control setting
  4861.     
  4862.     DEFAULTS:      value3 = "X"
  4863.     
  4864.     When you are breaking up a complex line into fields, PEEL can simplify
  4865.     matters considerably, because the line being interpreted gradually becomes
  4866.     less complex.
  4867.     
  4868.     Here is a simple example.  Let's say you have an input file containing a
  4869.     single line:
  4870.     
  4871.     AA/BB/CC/DD
  4872.     
  4873.     If you run this POM file against the input file:
  4874.     
  4875.     PEEL   x $FLINE "" "/"       <-- Strip out the AA and remove the /
  4876.     OUTEND |{x}
  4877.     PEEL   x $FLINE "" "/"       <-- Strip out the BB and remove the /
  4878.     OUTEND |{x}
  4879.     PEEL   x $FLINE "" "/"       <-- Strip out the CC and remove the /
  4880.     OUTEND |{x}
  4881.     OUTEND |{$FLINE}
  4882.     
  4883.     then the output file will look like this:
  4884.     
  4885.     AA
  4886.     BB
  4887.     CC
  4888.     DD
  4889.     
  4890.     What is happening is that $FLINE is gradually being stripped of the text
  4891.     that is being found.  After the first PEEL, $FLINE contains "BB/CC/DD",
  4892.     and so on.  After the final PEEL, $FLINE only contains "DD".
  4893.     
  4894.  
  4895.  
  4896.  
  4897.  
  4898.                                                                              80
  4899.     -------------------
  4900.     The Control Setting
  4901.     -------------------
  4902.     
  4903.     The "I" and "X" control parameters behave the same way as they do in the
  4904.     PARSE command: they specify whether or not the surrounding text is included
  4905.     in var1.  Take note, however, that the starting and ending characters
  4906.     are always removed from var2, along with the "found" text, regardless of
  4907.     the control parameter.  In other words, the control parameter only affects
  4908.     the first variable (x in the example above), not the second ($FLINE in the
  4909.     example).
  4910.     
  4911.     --------------------
  4912.     Parsing Empty Fields
  4913.     --------------------
  4914.     
  4915.     Consider the following commands:
  4916.     
  4917.     SET   z = ",,,JOHN,SMITH"
  4918.     PEEL  x z "2*," "3*,"
  4919.     
  4920.     There is nothing between the second and third comma, so the x variable
  4921.     is set to "" (an empty string).  After the PEEL command, the z variable
  4922.     will be two commas shorter (",JOHN,SMITH,23.00").  If you are trying to
  4923.     extract data from a comma-delimited line, this is probably not what you
  4924.     want (since it gets rid of two commas).  When taking apart a delimited
  4925.     file, it often makes sense to start peeling from the left side of the
  4926.     string.  Consider these commands:
  4927.     
  4928.     SET   z = ",,,JOHN,SMITH"
  4929.     PEEL  x z "" ","
  4930.     
  4931.     You are asking for everything from the first character to the first
  4932.     comma (which also happens to be the first character).  Obviously, there is
  4933.     nothing "between" the two characters, so the x variable would be set to ""
  4934.     (an empty string).  After the PEEL command, the z variable will be one
  4935.     comma shorter (",,JOHN,SMITH").
  4936.     
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942.  
  4943.  
  4944.  
  4945.  
  4946.  
  4947.  
  4948.  
  4949.  
  4950.  
  4951.  
  4952.  
  4953.                                                                              81
  4954.     --------------------------
  4955.     The Left-Peeling Technique
  4956.     --------------------------
  4957.     
  4958.     You can use the "left-peeling" technique to take apart an entire line.  This
  4959.     is especially useful when interpreting a comma-delimited file.
  4960.     
  4961.     SET   z = ",,MARY,JONES,"
  4962.     PEEL  a z "" ","                 <-- Sets the a variable to ""
  4963.     PEEL  b z "" ","                 <-- Sets the b variable to ""
  4964.     PEEL  c z "" ","                 <-- Sets the c variable to "MARY"
  4965.     PEEL  d z "" ","                 <-- Sets the d variable to "JONES"
  4966.     SET   e = z                      <-- Sets the e variable to ""
  4967.     
  4968.     The e variable is null because there is nothing after the last comma -- in
  4969.     other words, the final field is empty.  If the initial value of the z
  4970.     variable was ",,MARY,JONES,99" then the e variable would be set to "99".
  4971.     
  4972.     ----------------------
  4973.     The Leftover Technique
  4974.     ----------------------
  4975.     
  4976.     Sometimes you are faced with a parsing task in which the input lines are
  4977.     more than 255 characters long, yet there is no way to know where each
  4978.     field begins.  This makes it impossible to use the SPLIT command in the
  4979.     usual way.
  4980.     
  4981.     This type of problem generally arises when processing comma-delimited or
  4982.     tab-delimited files.
  4983.     
  4984.     Here is a sample POM file which handles input lines up to 300 characters
  4985.     long, provided that no field is more than 155 characters long.
  4986.     
  4987.  
  4988.  
  4989.  
  4990.  
  4991.  
  4992.  
  4993.  
  4994.  
  4995.  
  4996.  
  4997.  
  4998.  
  4999.  
  5000.  
  5001.  
  5002.  
  5003.  
  5004.  
  5005.  
  5006.  
  5007.  
  5008.                                                                              82
  5009.     SPLIT    1-100, 101-200, 201-300   <-- Process input lines in three segments
  5010.     IGNORE   $FLINE = ""               <-- Ignore any splits that yield nothing
  5011.     BEGIN    leftover <> ""            <-- See if we have anything left over
  5012.       APPEND   $FLINE leftover $FLINE  <-- Append what's left over
  5013.       SET      leftover = ""           <-- We've used up the left over data
  5014.     END
  5015.     BEGIN                              <-- Loop through the parts we can extract
  5016.       FINDPOSN x $09                   <-- Look for a tab
  5017.       BEGIN    x <> "0"                <-- See if we found a tab
  5018.         SET      foundtab = "Y"        <-- Yes, we found a tab
  5019.         PEEL     x $FLINE "" #09       <-- Peel away everything up to the tab
  5020.         OUTEND   |{x}                  <-- Process the text we peeled away
  5021.       ELSE
  5022.         SET      foundtab = "N"        <-- No, we didn't find a tab
  5023.         BEGIN    $SPLIT = "3"          <-- See if this is the last of the text
  5024.           OUTEND   |{$FLINE}           <-- Output whatever is left over
  5025.         ELSE
  5026.           SET      leftover = $FLINE   <-- Save this part for the next split
  5027.         END
  5028.       END
  5029.     AGAIN    foundtab = "Y"            <-- Continue if this segment had a tab
  5030.     
  5031.     
  5032.     
  5033.  
  5034.  
  5035.  
  5036.  
  5037.  
  5038.  
  5039.  
  5040.  
  5041.  
  5042.  
  5043.  
  5044.  
  5045.  
  5046.  
  5047.  
  5048.  
  5049.  
  5050.  
  5051.  
  5052.  
  5053.  
  5054.  
  5055.  
  5056.  
  5057.  
  5058.  
  5059.  
  5060.  
  5061.  
  5062.  
  5063.                                                                              83
  5064.     ============================================================================
  5065.                                 POSITIONAL COMMANDS
  5066.     ============================================================================
  5067.     
  5068.                                  ------------------
  5069.                                  General Discussion
  5070.                                  ------------------
  5071.     
  5072.     NOTE:  If you are a programmer, you may be tempted to use positional
  5073.            commands even when other Parse-O-Matic commands are more efficient.
  5074.            The positional approach is reminiscent of the parsing strategies
  5075.            used in traditional programming languages, so you may use them
  5076.            because of their familiarity.  The following material discusses
  5077.            this issue, to help you to create shorter, faster POM files.
  5078.     
  5079.     -----------------------------
  5080.     What are Positional Commands?
  5081.     -----------------------------
  5082.     
  5083.     Parse-O-Matic's positional commands let you work with the numeric position
  5084.     of one text string in another.  For example, if the variable xyz contains
  5085.     the value "ABCD":
  5086.     
  5087.     SEARCH   POSITION
  5088.     STRING    IN xyz    COMMENTS
  5089.     ------   --------   -----------------------------------------
  5090.     "A"        "1"      "A" appears in the 1st position of "ABCD"
  5091.     "AB"       "1"
  5092.     "ABCD"     "1"
  5093.     "C"        "3"      "C" appears in the 3rd position of "ABCD"
  5094.     "CD"       "3"
  5095.     "D"        "4"
  5096.     "AC"       "0"      "0" since "AC" does not appear in "ABCD"
  5097.     
  5098.     ----------------------------
  5099.     Why Use Positional Commands?
  5100.     ----------------------------
  5101.     
  5102.     Positional commands give you the precise control you need for certain
  5103.     difficult parsing tasks. For example, if you want to obtain the last three
  5104.     characters of a string of known length (e.g. "ABCDEFG"), the standard
  5105.     approach is:
  5106.     
  5107.     SET abc = "ABCDEFG"
  5108.     SET xyz = abc[5 7]
  5109.     
  5110.     However, if the length of the string is not known, you can not use the
  5111.     substrings in [square brackets].  (To make Parse-O-Matic run as fast as
  5112.     possible for standard parsing jobs, you can not use variables within
  5113.     square brackets.)
  5114.     
  5115.  
  5116.  
  5117.  
  5118.                                                                              84
  5119.     If the length of the string is not known, you need positional commands to
  5120.     obtain the last three characters.  Here is an example:
  5121.     
  5122.     SET    abc = "Unknown"
  5123.     SETLEN len abc
  5124.     CALC   lenminus = len "-" "2"
  5125.     COPY   xyz abc lenminus len
  5126.     
  5127.     The SETLEN command finds the length (i.e. the last position) of the abc
  5128.     variable.  In this case, the answer is "7", since "Unknown" is seven
  5129.     characters long.  The CALC command subtracts "2" from this length, setting
  5130.     the lenminus variable to "5".  Finally, the COPY command copies from
  5131.     position "5" to "7", setting the variable xyz to "own" -- the last three
  5132.     characters of the abc variable.
  5133.     
  5134.     -----------------
  5135.     A Cautionary Note
  5136.     -----------------
  5137.     
  5138.     Positional commands are useful for some applications, but many parsing jobs
  5139.     do not require them.  The commands SET, IF, PARSE and PEEL can usually do
  5140.     the same job with less effort. For example, the following approaches are
  5141.     equivalent:
  5142.     
  5143.                  STANDARD APPROACH       POSITIONAL APPROACH
  5144.                  -----------------       ---------------------
  5145.                  SET   abc "AB/CD"       SET      abc = "AB/CD"
  5146.                  PARSE xyz abc "/"       FINDPOSN n abc "/"
  5147.                                          COPY     xyz abc n+
  5148.     
  5149.     The positional approach requires more lines than the standard approach to
  5150.     extracting the characters after the "/" character.  Another problem is that
  5151.     because positional commands give you fine control of the parsing process,
  5152.     it is up to you to guard against exceptional situations.  Consider this
  5153.     example:
  5154.     
  5155.     FINDPOSN x $FLINE "/"
  5156.     CALC     x = x "+" "1"
  5157.     COPY     xyz $FLINE x
  5158.     
  5159.     If $FLINE (the current input line) contains the value "ABC/DEF":
  5160.     
  5161.     FINDPOSN sets x to "4" (the position of the "/" character)
  5162.     CALC     increases x to "5"
  5163.     COPY     sets xyz to "DEF" -- from position "5" to the end of $FLINE
  5164.     
  5165.     Unfortunately, a problem occurs if $FLINE does not contain a slash:
  5166.     
  5167.     FINDPOSN sets x to "0" (meaning the "/" was not found)
  5168.     CALC     increases x to "1"
  5169.     COPY     copies from position "1" to the end of $FLINE
  5170.     
  5171.  
  5172.  
  5173.                                                                              85
  5174.     This may not be what you intended.  If you want to return a null string
  5175.     when $FLINE does not contain a slash, you could use a single PARSE command:
  5176.     
  5177.     PARSE xyz $FLINE "/"
  5178.     
  5179.     This copies anything after the slash to the xyz variable.  If $FLINE does
  5180.     not contain a slash, xyz is set to "".
  5181.     
  5182.     The precise control provided by Parse-O-Matic's positional commands makes
  5183.     them indispensible for certain parsing applications.  Just remember that
  5184.     with added power comes added responsibility:  you will sometimes have to
  5185.     add extra code to handle unusual situations.
  5186.     
  5187.                                  ------------------
  5188.                                  The SETLEN Command
  5189.                                  ------------------
  5190.     
  5191.     FORMAT:        SETLEN var1 value1
  5192.     
  5193.     PURPOSE:       SETLEN sets var1 to the length of value1.
  5194.     
  5195.     Here is an example of the SETLEN command:
  5196.     
  5197.     SET    x = "ABCD"
  5198.     SETLEN y x
  5199.     
  5200.     This sets variable y to "4".
  5201.     
  5202.     One handy application for SETLEN is to underline text.  For example:
  5203.     
  5204.     SET     name = $FLINE[1 15]
  5205.     TRIM    name "B" " "
  5206.     SETLEN  nlen name
  5207.     SET     uline = ""
  5208.     PAD     uline "L" "-" nlen
  5209.     OUTEND  |{name}
  5210.     OUTEND  |{uline}
  5211.     
  5212.     If the input line contains the name "JOHN SMITH", the output would be:
  5213.     
  5214.     JOHN SMITH
  5215.     ----------
  5216.     
  5217.     For another example that does underlining, see "POM and Wildcards".
  5218.     
  5219.  
  5220.  
  5221.  
  5222.  
  5223.  
  5224.  
  5225.  
  5226.  
  5227.  
  5228.                                                                              86
  5229.                                  ------------------
  5230.                                  The DELETE Command
  5231.                                  ------------------
  5232.     
  5233.     FORMAT:        DELETE var1 value1 [value2]
  5234.     
  5235.     PURPOSE:       The DELETE command removes a range of characters (specified
  5236.                    as a starting and ending position) from a variable.
  5237.     
  5238.     PARAMETERS:    var1   is the variable from which characters will be removed
  5239.                    value1 is the starting position (e.g. "1" = First character)
  5240.                    value2 is the optional ending position; if it is omitted,
  5241.                           it is assumed to mean "the last character in var1"
  5242.     
  5243.     NOTES:         If value1 is null or "0", value1 = "1"
  5244.                    If value2 is null or "0", value2 = "last character in var1"
  5245.     
  5246.     ALTERNATIVES:  The PEEL, TRIM, CHANGE, SET and APPEND commands
  5247.     
  5248.     Here is an example of the DELETE command:
  5249.     
  5250.     SET    x = "ABC///DEF"
  5251.     DELETE x "4" "6"
  5252.     
  5253.     This deletes from position 4 to 6, so the variable x is set to "ABCDEF".
  5254.     
  5255.     If value2 is omitted, DELETE assumes you wish to delete everything from
  5256.     the starting position to the end of the string.  For example:
  5257.     
  5258.     SET    x = "ABC///DEF"
  5259.     DELETE x "4"
  5260.     
  5261.     This sets x to "ABC".
  5262.     
  5263.  
  5264.  
  5265.  
  5266.  
  5267.  
  5268.  
  5269.  
  5270.  
  5271.  
  5272.  
  5273.  
  5274.  
  5275.  
  5276.  
  5277.  
  5278.  
  5279.  
  5280.  
  5281.  
  5282.  
  5283.                                                                              87
  5284.                                   ----------------
  5285.                                   The COPY Command
  5286.                                   ----------------
  5287.     
  5288.     FORMAT:        COPY var1 value1 value2 [value3]
  5289.     
  5290.     PURPOSE:       The COPY command copies a range of characters (specified as
  5291.                    a starting and ending position) from a value to a variable.
  5292.     
  5293.     PARAMETERS:    var1   is the variable being set
  5294.                    value1 is the source value, from which you will copy text
  5295.                    value2 is the starting position (e.g. "1" = First character)
  5296.                    value3 is the optional ending position; if it is omitted,
  5297.                           it is assumed to mean "the last character in value1"
  5298.     
  5299.     NUMERICS:      Tabs, spaces and commas are stripped from value2 and value3
  5300.     
  5301.     NOTES:         If value2 is null or "0", value1 = "1"
  5302.                    If value3 is null or "0", value3 = "last char in value1"
  5303.     
  5304.     ALTERNATIVES:  The SET command
  5305.     
  5306.     Here is an example of the COPY command:
  5307.     
  5308.     SET    x = "ABC///DEF"
  5309.     COPY   y x "4" "6"
  5310.     
  5311.     This copies from position 4 to 6, so the variable y is set to "///".
  5312.     
  5313.     If value2 is omitted, COPY assumes you wish to copy everything from the
  5314.     starting position to the end of the string.  For example:
  5315.     
  5316.     SET    x = "ABC///DEF"
  5317.     COPY   y x "4"
  5318.     
  5319.     This sets y to "///DEF".
  5320.     
  5321.     To make your POM files easier to read, you might consider padding the
  5322.     COPY command with an equals sign to remind you that a variable is being
  5323.     set. For example:
  5324.     
  5325.     COPY   y = x "4" "6"
  5326.     
  5327.     This emphasizes that the variable y is being set to a substring of x.
  5328.     For more information about padding, see "Padding for Clarity".
  5329.     
  5330.  
  5331.  
  5332.  
  5333.  
  5334.  
  5335.  
  5336.  
  5337.  
  5338.                                                                              88
  5339.                                 -------------------
  5340.                                 The EXTRACT Command
  5341.                                 -------------------
  5342.     
  5343.     FORMAT:        EXTRACT var1 var2 value1 [value2]
  5344.     
  5345.     PURPOSE:       The EXTRACT command works like COPY, but removes the
  5346.                    characters from the source variable after copying them to
  5347.                    a variable.
  5348.     
  5349.     PARAMETERS:    var1   is the variable that will contain the characters
  5350.                           extracted from var2
  5351.                    var2   is the variable from which characters will be copied
  5352.                           to var1, then removed
  5353.                    value1 is the starting position (e.g. "1" = First character)
  5354.                    value2 is the optional ending position; if it is omitted,
  5355.                           it is assumed to mean "the last character in var2"
  5356.     
  5357.     NUMERICS:      Tabs, spaces and commas are stripped from value1 and value2
  5358.     
  5359.     NOTES:         If value1 is null or "0", value1 = "1"
  5360.                    If value2 is null or "0", value2 = "last character in var2"
  5361.     
  5362.     ALTERNATIVES:  The PEEL command
  5363.     
  5364.     Here is an example of the EXTRACT command:
  5365.     
  5366.     SET     x = "ABC///DEF"
  5367.     EXTRACT y x "4" "6"
  5368.     
  5369.     This copies from position 4 to 6, so the variable y is set to "///".
  5370.     The characters copied to variable y are removed from x, so that it now
  5371.     contains the value "ABCDEF".
  5372.     
  5373.     If value2 is omitted, EXTRACT assumes you wish to extract everything from
  5374.     the starting position to the end of the string.  For example:
  5375.     
  5376.     SET     x = "ABC///DEF"
  5377.     EXTRACT y x "4"
  5378.     
  5379.     This sets y to "///DEF", while the variable x is set to "ABC" (i.e. the
  5380.     original value for x, with the extracted characters removed).
  5381.     
  5382.  
  5383.  
  5384.  
  5385.  
  5386.  
  5387.  
  5388.  
  5389.  
  5390.  
  5391.  
  5392.  
  5393.                                                                              89
  5394.                                 --------------------
  5395.                                 The FINDPOSN Command
  5396.                                 --------------------
  5397.     
  5398.     FORMAT:        FINDPOSN var1 value1 value2 [value3 [value4]]
  5399.                             :    :      :       :       :
  5400.     MEANING:       1) Variable   Source Find    :       :
  5401.                    2) Variable   Source From    To      Control
  5402.     
  5403.     PURPOSE:       The FINDPOSN command finds one text string in another.  It
  5404.                    locates the starting or ending position of a string, or
  5405.                    a string delimited by one or two other strings.
  5406.     
  5407.     PARAMETERS:    var1   is the variable that will contain the position if
  5408.                           the string is found (e.g. "2" means it was found
  5409.                           in the second position of value1; "0" means the
  5410.                           string was not found)
  5411.                    value1 is the string being searched
  5412.                    value2 is the string being sought, or...
  5413.                              the left-most part of a string being sought
  5414.                    value3 is the right-most part of the string being sought;
  5415.                              if it is set to null (""), it is assumed to mean
  5416.                              "the last character in value1"
  5417.                    value4 is the control setting
  5418.     
  5419.     DEFAULTS:      value4 = "IS"
  5420.     
  5421.     ALTERNATIVES:  The SCANPOSN command
  5422.     
  5423.     SEE ALSO:      This section is much easier to understand if you have
  5424.                    studied "The Parse Command".
  5425.     
  5426.     There are two ways to use the FINDPOSN command:  the "Plain String Find"
  5427.     and the "Embedded String Find".  These are discussed below.
  5428.     
  5429.     ---------------------
  5430.     The Plain String Find
  5431.     ---------------------
  5432.     
  5433.     In its simplest form, the Plain String Find locates a string (value2) in
  5434.     another string (value1) and assigns its position to a variable (var1).
  5435.     Here is an example:
  5436.     
  5437.     FINDPOSN x $FLINE "Fred"
  5438.     
  5439.     This looks for the first occurrence of "Fred" in $FLINE (the current input
  5440.     line).  If $FLINE contains "Hello Fred!", the command will set the variable
  5441.     x to "7", since "Fred" starts in the seventh character position.
  5442.     
  5443.  
  5444.  
  5445.  
  5446.  
  5447.  
  5448.                                                                              90
  5449.     ---------------------------
  5450.     Using a Single Decapsulator
  5451.     ---------------------------
  5452.     
  5453.     Sometimes  you don't want to find the FIRST occurrence, but the second,
  5454.     third, and so on.  You can use a single decapsulator (see "The Parse
  5455.     Command") to specify this.  For example:
  5456.     
  5457.     SET      z = "This is the way to demonstrate the FINDPOSN command"
  5458.     FINDPOSN x z "the"
  5459.     FINDPOSN y z "2*the"
  5460.     
  5461.     The first FINDPOSN command finds the first occurrence of "the", using a
  5462.     plain string, so it sets the variable x to "9", since the first "the"
  5463.     starts in the ninth position.
  5464.     
  5465.     The second FINDPOSN command uses a decapsulator with the occurrence number
  5466.     "2*", which means "look for the second occurrence".  Thus, it sets the
  5467.     variable y to "32", since the second "the" occurs in that position.
  5468.     
  5469.     Incidentally, the first FINDPOSN could also have been written this way:
  5470.     
  5471.     FINDPOSN x z "1*the"
  5472.     
  5473.     which is another way of saying, "Look for the first occurrence".  However,
  5474.     if no occurrence number is specified, FINDPOSN assumes you are looking for
  5475.     the first occurrence.
  5476.     
  5477.     ----------------------------
  5478.     The Encapsulated String Find
  5479.     ----------------------------
  5480.     
  5481.     NOTE:  The Encapsulated String Find is very similar to the PARSE command.
  5482.            If you do not find the following discussion sufficiently
  5483.            instructive, you can gain some additional insight by reading the
  5484.            section of this manual entitled "The Parse Command".
  5485.     
  5486.     The Encapsulated String Find looks for a string that is encapsulated by
  5487.     (i.e. located between) two other strings.  This is useful if your input
  5488.     data contains text that is surrounded by delimiters.  One common example is
  5489.     the "comma-delimited" file (see "Why You Need Parse-O-Matic -- An Example"
  5490.     for a sample).  Here is another situation where data is surrounded by
  5491.     delimiters:
  5492.     
  5493.     |Mouse |Gazelle|Mouse  |Elephant|
  5494.     |Dog   |Giraffe|Elk    |Mongoose|
  5495.     |Monkey|Snake  |Caribou|Trout   |
  5496.     
  5497.     One can imagine an application that would create tabular data like this --
  5498.     cleverly (but annoyingly) reducing the column widths to the minimum.  This
  5499.     would make the column starting and ending positions unpredictable.
  5500.     
  5501.  
  5502.  
  5503.                                                                              91
  5504.     You could use the PARSE command to obtain values from each column, but if
  5505.     you have a lot of data, it would be more efficient to determine the
  5506.     starting and ending positions at the outset.
  5507.     
  5508.     Let's say you wanted to extract the third column.  You could set up your
  5509.     POM file like this:
  5510.     
  5511.     BEGIN startposn = ""
  5512.       FINDPOSN startposn $FLINE "3*|" "4*|" "XS"
  5513.       FINDPOSN endposn   $FLINE "3*|" "4*|" "XE"
  5514.       HALT     startposn = "0" "Missing delimiter!"
  5515.     END
  5516.     COPY animal $FLINE startposn endposn
  5517.     OUTEND |{animal}
  5518.     
  5519.     The lines between the BEGIN and END are run only once for the entire
  5520.     parsing job, since they set the startposn variable to something other than
  5521.     a null ("") string.  (See "Uninitialized and Persistent Variables")
  5522.     
  5523.     The first FINDPOSN command uses the decapsulators "3*|" and "4*|" to locate
  5524.     the text between the third and fourth "|" delimiters, but because of the
  5525.     "XS" control value (described later), startposn is set to the position
  5526.     AFTER the delimiter. (Briefly, "XS" means "exclude the found text, and
  5527.     refer to the starting position of the text that follows it.)  Thus, the
  5528.     variable startposn is set to "12"; "Mouse" starts in the twelfth position.
  5529.     
  5530.     The second FINDPOSN command sets the ending position (endposn) in a similar
  5531.     way.  It finds the third and fourth "|" delimiters, but because of the "XE"
  5532.     control setting, it sets endposn to the position BEFORE the fourth
  5533.     delimiter. (Briefly, "XE" means "exclude the found text, and refer to the
  5534.     ending position of the text that precedes it.)
  5535.     
  5536.     The HALT command is simply a safeguard to ensure that the input data
  5537.     follows the correct format.  If the first FINDPOSN fails to find the
  5538.     third or fourth "|" delimiter, it will set startposn to "0" (meaning "not
  5539.     found").
  5540.     
  5541.     The COPY command copies $FLINE (the current input line) from the starting
  5542.     position (startposn) to the ending position (endposn).  This value is then
  5543.     output by the OUTEND command.
  5544.     
  5545.  
  5546.  
  5547.  
  5548.  
  5549.  
  5550.  
  5551.  
  5552.  
  5553.  
  5554.  
  5555.  
  5556.  
  5557.  
  5558.                                                                              92
  5559.     ----------------
  5560.     Control Settings
  5561.     ----------------
  5562.     
  5563.     The control settings give you precise control of the part of the string
  5564.     to which you are referring.  Valid control settings are:
  5565.     
  5566.     SETTING  MEANING
  5567.     -------  -------
  5568.       IS     Include found text and report where the  entire   text starts
  5569.       IE     Include found text and report where the  entire   text ends
  5570.       XS     Exclude found text and report where the delimited text starts
  5571.       XE     Exclude found text and report where the delimited text ends
  5572.     
  5573.     NOTE:  While FINDPOSN greatly resembles the PARSE command, the default
  5574.            control setting is different.  In PARSE, the control setting is
  5575.            assumed to be "X" if it is omitted.  In FINDPOSN, however, the
  5576.            control setting is assumed to be "IS" if it is omitted.
  5577.     
  5578.     Let us assume that the we set the variable z as follows:
  5579.     
  5580.     SET z = "ABzzzCDEFzzzGH"
  5581.     
  5582.     This produces the following results:
  5583.     
  5584.             COMMAND                            VALUE FOR x VARIABLE
  5585.             ---------------------------------  --------------------
  5586.             FINDPOSN x z "1*zzz" "2*zzz" "IS"           "3"
  5587.             FINDPOSN x z "1*zzz" "2*zzz" "XS"           "6"
  5588.             FINDPOSN x z "1*zzz" "2*zzz" "XE"           "9"
  5589.             FINDPOSN x z "1*zzz" "2*zzz" "IE"          "12"
  5590.     
  5591.     The following illustration may make the results easier to understand:
  5592.     
  5593.     +------------------------------------------------------------------------+
  5594.     |                                                                        |
  5595.     | Measuring Scale:             12345678901234                            |
  5596.     |                              --------------                            |
  5597.     |         Command: FINDPOSN x "ABzzzCDEFzzzGH" "zzz" "2*zzz" "<control>" |
  5598.     |                                |  |  |  |                              |
  5599.     |   Control Value:              IS XS XE IE                              |
  5600.     |         Results:               3  6  9 12                              |
  5601.     |                                                                        |
  5602.     +------------------------------------------------------------------------+
  5603.     
  5604.     In the example, the control values have the following specific meanings:
  5605.     
  5606.     "IS" ("Include, Start") = start of entire text (from "1*zzz" to "2*zzz")
  5607.     "XS" ("Exclude, Start") = start of text after  the "from" item ("1*zzz")
  5608.     "XE" ("Exclude, End")   =  end  of text before the  "to"  item ("2*zzz")
  5609.     "IE" ("Include, End")   =  end  of entire text (from "1*zzz" to "2*zzz")
  5610.     
  5611.  
  5612.  
  5613.                                                                              93
  5614.     ------------------
  5615.     Insoluble Searches
  5616.     ------------------
  5617.     
  5618.     FINDPOSN returns "0" (zero) when it can not find a string, or if it is
  5619.     presented with an insoluble dilemma.  Here are some examples:
  5620.     
  5621.     FINDPOSN x "CatDog" "Moose"        <-- "Moose" can not be found
  5622.     FINDPOSN x "ABCDEF" "A" "G"        <-- "G" can not be found
  5623.     FINDPOSN x "ABCDEF" "A" "2*E"      <-- There is no second "E"
  5624.     
  5625.     Here is another insoluble search:
  5626.     
  5627.     FINDPOSN x "ABCDEF" "C" "D" "XS"
  5628.     FINDPOSN x "ABCDEF" "C" "D" "XE"
  5629.     
  5630.     There is nothing between the "from" and "to" delimiters. Since we are
  5631.     excluding the delimiters themselves (with "XS" and "XE" specifications), we
  5632.     can not provide a "start" or "end" value for what we found -- we didn't
  5633.     find anything!  Hence, we have nothing for which to return a starting or
  5634.     ending position.
  5635.     
  5636.     ------------------
  5637.     Null Decapsulators
  5638.     ------------------
  5639.     
  5640.     Consider these next two commands:
  5641.     
  5642.     FINDPOSN x "ABCDEF" "F" "" "XS"
  5643.     FINDPOSN x "ABCDEF" "F" "" "XE"
  5644.     
  5645.     What comes between "F" and the end of the string?  Bear in mind, however,
  5646.     that when you use a null ("") to mean "the last character", it is not
  5647.     excluded (see "The Null Decapsulator" in the section entitled "The Parse
  5648.     Command", for a discussion).  Thus, the two FINDPOSN commands "find" the
  5649.     final character "F", and both return "6".
  5650.     
  5651.     These both return "6" because the "F" is both the starting and ending
  5652.     position of what we found, and we included (rather than excluded) the
  5653.     starting and ending delimiters ("F" and the last character, respectively).
  5654.     
  5655.     Similarly, the following commands return a "1":
  5656.     
  5657.     FINDPOSN x "ABCDEF" "" "A" "XS"
  5658.     FINDPOSN x "ABCDEF" "" "A" "XE"
  5659.     
  5660.     Even though there is nothing between "A" and "the first character", the
  5661.     first character is not excluded, since we are using a null decapsulator.
  5662.     As a result, we find the string "A" and return its position, which is "1".
  5663.     
  5664.  
  5665.  
  5666.  
  5667.  
  5668.                                                                              94
  5669.     ---------------------
  5670.     Finding The Last Word
  5671.     ---------------------
  5672.     
  5673.     One common use for FINDPOSN is to find the last occurrence of a word in a
  5674.     line of text.  Consider the following lines:
  5675.     
  5676.     SET       z = "Parse-O-Matic is a fine product!"
  5677.     FINDPOSN  x z ">* " "" "XS"
  5678.     
  5679.     This will set the x variable to 25 (the position of the final word).  The
  5680.     command looks for the last "space" character (which is in position 24),
  5681.     then (because of the "XS" control) returns the position of the character
  5682.     following it.
  5683.     
  5684.     ---------------
  5685.     Who Needs This?
  5686.     ---------------
  5687.     
  5688.     At this point, you may be wondering, "Why do I need to have this kind of
  5689.     precise control?"  Well, in most cases you don't, so you will tend to use
  5690.     the "Plain String Find" (described earlier).  However, certain complex
  5691.     parsing applications demand that you make a distinction between the text
  5692.     that encapsulated a piece of text, and the encapsulated text itself.  When
  5693.     faced with this kind of task, you will see that Parse-O-Matic's FINDPOSN
  5694.     command lets you accomplish in one line what would take dozens of lines in
  5695.     a traditional programming language.
  5696.     
  5697.                                 --------------------
  5698.                                 The SCANPOSN Command
  5699.                                 --------------------
  5700.     
  5701.     FORMAT:        SCANPOSN var1 var2 value1 value2 [value3]
  5702.                             :    :    :      :        :
  5703.     MEANING:                from to   source scanlist control
  5704.     
  5705.     PURPOSE:       SCANPOSN searches the source value for one of the scanterms
  5706.                    in the scanlist (see "Terminology", below).  SCANPOSN finds
  5707.                    out which scanterm provides the best match, then returns the
  5708.                    "from" (starting) and "to" (ending) positions of that
  5709.                    scanterm in the source value.
  5710.     
  5711.     TERMINOLOGY:   scanterm  An item in a scanlist; one of the things you are
  5712.                              searching the source value for.
  5713.                    scanlist  A list of scanterms.  Here is an example of a
  5714.                              scanlist:  "/Mr/Mrs/Ms"
  5715.     
  5716.     PARAMETERS:    var1   is the variable that will contain the starting
  5717.                           position if one of the scanterms is found (e.g. "2"
  5718.                           means it was found in the second position of value1;
  5719.                           "0" means SCANPOSN did not find any of the scanterms)
  5720.                    var2   is the variable that will contain the ending position
  5721.                           if one of the scanterms is found
  5722.  
  5723.                                                                              95
  5724.                    value1 is the source string -- the string being searched
  5725.                    value2 is the scanlist (see "Terminology", above)
  5726.                    value3 is the optional control string
  5727.     
  5728.     DEFAULTS:      value3 = "I" (i.e. Ignore case)
  5729.     
  5730.     ALTERNATIVES:  The FINDPOSN command
  5731.     
  5732.     A common requirement in parsing is to find out if one of several strings can
  5733.     be found in another string.  For example, you might want to find out if a
  5734.     name starts with a "salutation" (Mr., Mrs., Ms.).  You can do this by looping
  5735.     through the various strings and comparing each one, but SCANPOSN lets you do
  5736.     all this with a single command.
  5737.     
  5738.     For example, to search for a salutation in a string:
  5739.     
  5740.     SCANPOSN from to $FLINE "/Mr./Mrs./Miss/Ms."
  5741.     
  5742.     If $FLINE (the line just read from the input file) contains one of the
  5743.     scanterms in the scanlist, SCANPOSN will set the "from" and "to" variables.
  5744.     Thus, if $FLINE contains "Ms. Mary Jones", the "from" variable is set to "1"
  5745.     and the "to" variable is set to "3" (since "Ms." goes from positions 1 to 3
  5746.     in $FLINE).
  5747.     
  5748.     If none of the scanterms is found, the "from" variable is set to "0".  Thus,
  5749.     if $FLINE contains "John Smith", no salutation is found, and the SCANPOSN
  5750.     command shown above will set the "from" variable to "0".
  5751.     
  5752.     ------------
  5753.     The Scanlist
  5754.     ------------
  5755.     
  5756.     The scanlist can contain one or more scanterms.  The FIRST character in the
  5757.     scanlist is interpreted as the delimiter (separator) for the scanterms.
  5758.     Thus, the following scanlists are all valid:
  5759.     
  5760.     "/Mr./Mrs./Miss/Ms."                          <-- Delimiter is:   /
  5761.     "xMr.xMrs.xMissxMs."                          <-- Delimiter is:   x
  5762.     "@Library@School@Gymnasium@Clinic/Hospital"   <-- Delimiter is:   @
  5763.     "/Cow"                                        <-- Delimiter is:   /
  5764.     
  5765.     The first example ("/Mr./Mrs./Miss/Ms.") has already been demonstrated.  The
  5766.     second example uses the letter "x" as a delimiter.  This would cause a
  5767.     problem if one of the scanterms contained an "x", since it would be treated
  5768.     as TWO scanterms.  For example:
  5769.     
  5770.     "xJohnxTrixiexFred"
  5771.     
  5772.     The name "Trixie" contains an "x", so it would be broken down into two
  5773.     scanterms ("Tri" and "ie").  You should always choose a scanlist delimiter
  5774.     that does not appear in the list of scanterms.
  5775.     
  5776.  
  5777.  
  5778.                                                                              96
  5779.     -----------------------
  5780.     Accommodating Variation
  5781.     -----------------------
  5782.     
  5783.     When you design a scanlist, you should take into account the possibility
  5784.     that the input might contain strange variations.  Consider this command:
  5785.     
  5786.     SCANPOSN x y "Mr John Smith" "/Mr./Mrs./Ms."
  5787.     
  5788.     This will set the x variable to "0" because the "Mr" is followed by a space,
  5789.     not a period.  A more "forgiving" command would be:
  5790.     
  5791.     SCANPOSN x y "Mr John Smith" "/Mr./Mrs./Ms./Mr /Mrs /Ms "
  5792.     
  5793.     This would successfully locate the "Mr " string, and set x to "1" and y to
  5794.     "3". (The "3" points to the space.)
  5795.     
  5796.     ------------------------------
  5797.     Handling Prefixes and Suffixes
  5798.     ------------------------------
  5799.     
  5800.     When designing a scanlist, you should consider that a scanterm might be
  5801.     part of a word.  For example:
  5802.     
  5803.     SCANPOSN x y "Mississipi Sue" "/MR./MRS./MISS/MS."
  5804.     
  5805.     This will find the "Miss" in Mississippi, even though this is not part of
  5806.     a salutation.  A more appropriate command would be:
  5807.     
  5808.     SCANPOSN x y "Mississipi Sue" "/MR./MRS./MISS /MS."
  5809.     
  5810.     The space after "Miss" in the scanlist ensures that if it is found, it will
  5811.     be separate from any word following it.
  5812.     
  5813.     The trailing space is not necessary for the scanterm "MR.", since no word
  5814.     contains a period.  However, if you do include spaces after the periods
  5815.     (as in "/MR. /MRS. /MISS /MS. ") it may simplify your subsequent parsing
  5816.     operations.
  5817.     
  5818.     You must also take suffixes into account.  For example:
  5819.     
  5820.     SCANPOSN x y "Zinc Enterprises" "/INC/CO/ENTERPRISES"
  5821.     
  5822.     This will find the "inc" in "Zinc".  You can add a space in front of each
  5823.     scanterm to ensure that it is separated from any other word:
  5824.     
  5825.     SCANPOSN x y "Zinc Enterprises" "/ INC/ CO/ ENTERPRISES"
  5826.     
  5827.     You may be tempted to put spaces on both sides of a word, to handle both
  5828.     prefixes and suffixes.  However, consider this example:
  5829.     
  5830.     SCANPOSN x y "Wazoo Inc" "/ INC / CO / ENTERPRISES "
  5831.     
  5832.  
  5833.                                                                              97
  5834.     None of the scanterms is found, because the "Inc" in the source string
  5835.     does not end in a space.  You can address this kind of problem with the
  5836.     control settings (described next).
  5837.     
  5838.     ----------------------
  5839.     Controlling the Search
  5840.     ----------------------
  5841.     
  5842.     Unless otherwise instructed, SCANPOSN will find the first scanterm that
  5843.     appears anywhere in the source string, and return its start and end
  5844.     positions.  You can modify this behavior by using the optional control
  5845.     parameter (value3).
  5846.     
  5847.     The control parameter contains one or more characters, each of which has
  5848.     a special meaning.
  5849.     
  5850.     CHARACTER   MEANING
  5851.     ---------   -------
  5852.        <        Find the leftmost match
  5853.        >        Find the rightmost match
  5854.        I        Ignore case (e.g. Xyz matches XYZ)
  5855.        M        Match case (e.g. Xyz does not match XYZ)
  5856.     
  5857.     Here are some valid control settings:
  5858.     
  5859.     SETTING   MEANING
  5860.     -------   -------
  5861.      "<M"     Find the leftmost match, which much match case
  5862.      "<I"     Find the leftmost match, ignoring case
  5863.      ">M"     Find the rightmost match, which must match case
  5864.      "M"      Find any match, but the case must be the same
  5865.     
  5866.     NOTES:  If neither "I" nor "M" are specified, SCANPOSN assumes "I".
  5867.             If neither "<" nor ">" are specified, SCANPOSN does a "Find-Any"
  5868.             search (explained below).
  5869.     
  5870.     -----------------------------
  5871.     Leftmost, Rightmost, Find-Any
  5872.     -----------------------------
  5873.     
  5874.     The ">" (rightmost) control setting tells SCANPOSN to find the scanterm that
  5875.     has the highest "to" value with the lowest "from" value.  This means that
  5876.     ALL of the scanterms are evaluated.  Consider this command:
  5877.     
  5878.     SCANPOSN x y "SHREWxxxCATxxxMOUSExxx" "/CAT/DOGGY/MOUSE/ELK" ">"
  5879.     
  5880.     SCANPOSN finds "CAT", but continues looking to see if there are any better
  5881.     matches to the right.  Eventually it finds MOUSE and sets x to "15" and y
  5882.     to "19" (pointing at "MOUSE").
  5883.     
  5884.     If you use the "<" (leftmost) parameter, SCANPOSN will check all the
  5885.     scanterms to find out which one has the lowest "from" position with the
  5886.     highest "to" value.
  5887.  
  5888.                                                                              98
  5889.     SCANPOSN x y "SHREWxxxCATxxxMOUSExxx" "/CAT/DOGGY/MOUSE/ELK" "<"
  5890.     
  5891.     This will set x to "9" and y to "11" (pointing at "CAT").
  5892.     
  5893.     If you do not specify "<" or ">", SCANPOSN finds the first scanterm it can,
  5894.     and ignores the rest.
  5895.     
  5896.     SCANPOSN x y "SHREWxxxCATxxxMOUSExxx" "/CAT/DOGGY/MOUSE/ELK"
  5897.     
  5898.     The first scanterm is "CAT", and this can be found at positions 9 to 11.
  5899.     SCANPOSN will return those values, and ignore the rest of the scanterms.
  5900.     
  5901.     The absence of a "<" or ">" is known as a "Find-Any" search.  You can use
  5902.     this if you want to know if one of the scanterms appears in the source
  5903.     string, but you are not interested in finding out which one.
  5904.     
  5905.     ------------------------
  5906.     The Best Match Principle
  5907.     ------------------------
  5908.     
  5909.     NOTE:  The "Best Match" principle does not apply to the "Find-Any" search.
  5910.            It applies only to the Leftmost ("<") and Rightmost (">") searches.
  5911.     
  5912.     To use the SCANPOSN command effectively, you must understand the concept of
  5913.     "the best match".  This can be illustrated with an example:
  5914.     
  5915.     SCANPOSN x y "MegaWhizco International" "/CO/WHIZCO/MEGAWHIZ" ">"
  5916.     
  5917.     The SCANPOSN command finds the scanterm CO at positions 5 to 6.  However, it
  5918.     continues looking for an even better match.
  5919.     
  5920.     It finds that WHIZCO is just as far to the right (i.e. it ends at position
  5921.     6), but has a lower starting position.  This makes it a "better" match.
  5922.     
  5923.     The next scanterm (MEGAWHIZ) has a lower starting position, but its ending
  5924.     position is not as good (i.e. not as far to the right).  It is rejected
  5925.     because we are looking for the rightmost string.
  5926.     
  5927.     As a result, SCANPOSN will set x to "1" and y to "6".
  5928.     
  5929.     In other words, when SCANPOSN is looking for the rightmost scanterm, it will
  5930.     first identify the "found" scanterms which have the highest ending position,
  5931.     and then choose the longest one.
  5932.     
  5933.     Here is an example using a leftmost search:
  5934.     
  5935.     SCANPOSN x y "Our catalog is enclosed" "CAT/MOOSE/CATALOG/DOG" "<"
  5936.     
  5937.     The SCANPOSN finds CAT at positions 5 to 7, but as it continues checking
  5938.     the scanterms, it finds that CATALOG is just as far to the left (i.e. it
  5939.     starts at position 5), but it is a better match since it has a higher ending
  5940.     position.
  5941.     
  5942.  
  5943.                                                                              99
  5944.     As a result, SCANPOSN will set x to "5" and y to "11".
  5945.     
  5946.     The "Best Match" principle does not affect "Find-Any" searches.  For
  5947.     example:
  5948.     
  5949.     SCANPOSN x y "Our catalog is enclosed" "CAT/MOOSE/CATALOG/DOG"
  5950.     
  5951.     This sets x to "5" and y to "7".  Since this is a "Find-Any" search (i.e.
  5952.     neither "<" nor ">" are specified in the control settings), SCANPOSN stops
  5953.     looking as soon as it has found a match.
  5954.     
  5955.     When doing a Find-Any search, you can not be sure if any of the other scan
  5956.     terms appear in the source string.  For example:
  5957.     
  5958.     SCANPOSN x y "Our cat and dog are upstairs" "CAT/DOG"
  5959.     
  5960.     This will find CAT and stop looking for additional matches.  If you change
  5961.     the order of the scanlist, you will get different values:
  5962.     
  5963.     SCANPOSN x y "Our cat and dog are upstairs" "DOG/CAT"
  5964.     
  5965.     Thus, a Find-Any search is useful only for detecting if one of the scanterms
  5966.     appears in the source string.  After doing a Find-Any search, you can check
  5967.     if the "from" value is "0" (meaning no scanterms were found).  If it is not
  5968.     "0", it means one of the terms WAS found.  For example:
  5969.     
  5970.     SET      source   = "Our cat catalog is enclosed"
  5971.     SET      scanlist = "CATALOG/MOOSE/CAT/DOG"
  5972.     SCANPOSN from to source scanlist
  5973.     BEGIN    from = "0"
  5974.       OUTEND  |None of the scanterms appeared in the string {source}
  5975.     ELSE
  5976.       OUTEND  |At least one of the scanterms appears in the string {source}
  5977.     END
  5978.     
  5979.     
  5980.     
  5981.  
  5982.  
  5983.  
  5984.  
  5985.  
  5986.  
  5987.  
  5988.  
  5989.  
  5990.  
  5991.  
  5992.  
  5993.  
  5994.  
  5995.  
  5996.  
  5997.  
  5998.                                                                             100
  5999.     ============================================================================
  6000.                                    DATE COMMANDS
  6001.     ============================================================================
  6002.     
  6003.                                  ------------------
  6004.                                  General Discussion
  6005.                                  ------------------
  6006.     
  6007.     Parse-O-Matic's date-oriented commands provide you with a convenient way to
  6008.     work with dates.  While you can accomplish the same thing using other
  6009.     Parse-O-Matic commands (LOOKUP, PAD etc.), the date functions are optimized
  6010.     for speed, so if your parsing job does a lot of date-format conversions, it
  6011.     will run faster.
  6012.     
  6013.     --------------------
  6014.     The POMDATE.CFG File
  6015.     --------------------
  6016.     
  6017.     When a date command is first executed, Parse-O-Matic reads in a file named
  6018.     POMDATE.CFG.  (The method by which Parse-O-Matic finds the file is
  6019.     discussed in the section "How Parse-O-Matic Searches for a File".)
  6020.     
  6021.     POMDATE.CFG is a self-documenting text file that contains the default
  6022.     date format string (explained later), and the names of the twelve months.
  6023.     You can edit this file with a standard text editor, or a word-processor in
  6024.     "generic text" mode.
  6025.     
  6026.     As originally supplied with Parse-O-Matic, the default date format string
  6027.     is "?y/?n/?d", which produces YY/MM/DD dates (e.g. July 1 1998 becomes
  6028.     98/07/01). You can change this to reflect your own preference.
  6029.     
  6030.     If you are parsing data in a language other than English, you can also
  6031.     change the names of the months.
  6032.     
  6033.     ------------
  6034.     Date Formats
  6035.     ------------
  6036.     
  6037.     A date format is a sequence of characters that briefly describes the
  6038.     appearance of a date.  For example, the format "Y-T-?n" describes a
  6039.     year/month/day format that looks like this:  1998-JULY-02
  6040.     
  6041.     The following characters have a special meaning in the date format
  6042.     string:  d M m n T t Y y ?
  6043.     
  6044.     For these special characters, uppercase and lowercase are important.
  6045.     For example, "T" is not the same as "t".
  6046.     
  6047.     All characters other than the special characters are interpreted "as-is",
  6048.     and are included in the final date string.
  6049.     
  6050.  
  6051.  
  6052.  
  6053.                                                                             101
  6054.     The following table explains the meaning of the special characters used
  6055.     to specify year, month and day, using the date July 2, 1998 for the
  6056.     examples:
  6057.     
  6058.          CHAR  MEANING                     SAMPLE FORMAT  SAMPLE RESULT
  6059.          ----  --------------------------  -------------  -------------
  6060.           Y    4-digit year                d-m-Y          2-Jul-1998
  6061.           y    1- or 2-digit year          d-m-y          2-Jul-98
  6062.           n    1- or 2-digit month         d/n/y          2/7/98
  6063.           m    3-letter month              d/m/y          2/Jul/98
  6064.           M    3-letter month (uppercase)  d M y          2 JUL 98
  6065.           t    Month                       t d, Y         July 2, 1998
  6066.           T    Month (uppercase)           T d Y          JULY 2 1998
  6067.           d    Day                         y/m/d          98/7/2
  6068.     
  6069.     The ? character can be used in the date format to pad out one-digit
  6070.     values to two digits.  The following table uses the date February 3, 2001
  6071.     for the examples:
  6072.     
  6073.                        SAMPLE DATE FORMAT   SAMPLE RESULT
  6074.                        ------------------   -------------
  6075.                        y-?n-?d              1-02-03
  6076.                        ?y/m/?d              01/Feb/03
  6077.                        ?n/?d Y              02/01 2001
  6078.                        t '?y                February '01
  6079.     
  6080.     As the last example shows, it is not necessary to use month, day and year;
  6081.     you can omit any item to obtain an abbreviated date.
  6082.     
  6083.  
  6084.  
  6085.  
  6086.  
  6087.  
  6088.  
  6089.  
  6090.  
  6091.  
  6092.  
  6093.  
  6094.  
  6095.  
  6096.  
  6097.  
  6098.  
  6099.  
  6100.  
  6101.  
  6102.  
  6103.  
  6104.  
  6105.  
  6106.  
  6107.  
  6108.                                                                             102
  6109.                                  -----------------
  6110.                                  The TODAY Command
  6111.                                  -----------------
  6112.     
  6113.     FORMAT:        TODAY var1 [value1]
  6114.     
  6115.     PURPOSE:       The TODAY command sets a variable (var1) to today's date, in
  6116.                    a variety of formats.
  6117.     
  6118.     DEFAULTS:      If value1 is not specified, TODAY uses the default date
  6119.                    format, which is specified in the file POMDATE.CFG.
  6120.     
  6121.     NOTES:         For a discussion of date formats (including the default date
  6122.                    format), see the "General Discussion" section at the
  6123.                    beginning of this chapter.
  6124.     
  6125.     SEE ALSO:      "The Date Command"
  6126.     
  6127.     Assuming today's date is July 1 1998, here are some examples:
  6128.     
  6129.                COMMAND              THE VARIABLE xyz IS SET TO...
  6130.                -------------------  -----------------------------
  6131.                TODAY xyz            The default date format
  6132.                TODAY xyz ""         The default date format
  6133.                TODAY xyz "Y-M-?d"   1998-JUL-01
  6134.                TODAY xyz "t d Y"    July 1 1998
  6135.                TODAY xyz "t 'y"     July '98
  6136.     
  6137.     As the last example shows, it is not necessary to use month, day and year;
  6138.     you can omit any item to obtain an abbreviated date.
  6139.     
  6140.  
  6141.  
  6142.  
  6143.  
  6144.  
  6145.  
  6146.  
  6147.  
  6148.  
  6149.  
  6150.  
  6151.  
  6152.  
  6153.  
  6154.  
  6155.  
  6156.  
  6157.  
  6158.  
  6159.  
  6160.  
  6161.  
  6162.  
  6163.                                                                             103
  6164.                                   ----------------
  6165.                                   The DATE Command
  6166.                                   ----------------
  6167.     
  6168.     FORMAT:        DATE var1 value1 value2 value3 [value4]
  6169.     
  6170.     PURPOSE:       The DATE command sets a variable (var1) to given year
  6171.                    (value1), month (value2) and day (value3), or a subset of
  6172.                    these items, in a variety of formats, as specified by the
  6173.                    format string (value4).
  6174.     
  6175.     PARAMETERS:    var1   is the variable being set
  6176.                    value1 is the year (e.g. "1998" or "98")
  6177.                    value2 is the month (e.g. "1" = January)
  6178.                    value3 is the day (1 to 31)
  6179.                    value4 is the date format
  6180.     
  6181.     NUMERICS:      Tabs, spaces and commas are stripped from value1, 2 and 3
  6182.     
  6183.     DEFAULTS:      If value4 is omitted, DATE uses the default date format,
  6184.                    which is specified in the file POMDATE.CFG.
  6185.     
  6186.     NOTES:         For a discussion of date formats (including the default date
  6187.                    format), see the "General Discussion" section at the
  6188.                    beginning of this chapter.
  6189.     
  6190.     SEE ALSO:      "The Today Command"
  6191.     
  6192.     Assuming the date being set is July 1 1998, here are some examples:
  6193.     
  6194.     COMMAND                             THE VARIABLE xyz IS SET TO...
  6195.     ----------------------------------  -----------------------------
  6196.     DATE xyz "98"   "07" "01"           The default date format
  6197.     DATE xyz "1998" "07" "01" ""        The default date format
  6198.     DATE xyz "98"    "7"  "1" "Y-M-?d"  1998-JUL-01
  6199.     DATE xyz "98"   "07" "01" "t d Y"   July 1 1998
  6200.     DATE xyz "98"    "7" "01" "t 'y"    July '98
  6201.     DATE xyz "98"    "7"   "" "t 'y"    July '98
  6202.     
  6203.     As the last two examples show, it is not necessary to use month, day and
  6204.     year; you can omit any item to obtain an abbreviated date.
  6205.     
  6206.     If a date is outside a valid range, Parse-O-Matic halts with an error.
  6207.     Acceptable value ranges are:  Year 0 to 9999; Month 1 to 12; Day 1 to 31
  6208.     
  6209.     If the year is between 0 and 99, Parse-O-Matic makes the following
  6210.     assumptions:
  6211.     
  6212.     - If the number is between 80 and 99, it means 1980 to 1999
  6213.     - If the number is between  0 and 79, it means 2000 to 2079
  6214.     
  6215.     Parse-O-Matic does not check that a date is "possible", so you could set
  6216.     a date to "February 31, 2001", even though February never has 31 days.
  6217.  
  6218.                                                                             104
  6219.                                --------------------
  6220.                                The MONTHNUM Command
  6221.                                --------------------
  6222.     
  6223.     FORMAT:        MONTHNUM var1 value1
  6224.     
  6225.     PURPOSE:       The MONTHNUM command sets the month number of a given month.
  6226.     
  6227.     ALTERNATIVES:  The LOOKUP command
  6228.     
  6229.     Here is an example of the MONTHNUM command:
  6230.     
  6231.     MONTHNUM xyz "February"
  6232.     
  6233.     This will set the variable xyz to "2".
  6234.     
  6235.     The comparison is performed on the basis of the number of characters
  6236.     available, without regard to case, so the following would also work:
  6237.     
  6238.     MONTHNUM xyz "FEB"
  6239.     
  6240.     If the result is ambiguous, Parse-O-Matic returns the first match.  For
  6241.     example:
  6242.     
  6243.     MONTHNUM xyz "JU"
  6244.     
  6245.     This will set xyz to "6", although it could refer to either June or July.
  6246.     
  6247.     If MONTHNUM can not find a match, it will return a null ("") string.
  6248.     For example:
  6249.     
  6250.     MONTHNUM xyz "ZZZ"
  6251.     
  6252.     Since no month starts with "ZZZ", this will set xyz to "".
  6253.     
  6254.     If you are writing a Parse-O-Matic application that will be run in several
  6255.     languages (using different POMDATE.CFG files), you should carefully study
  6256.     the names of the months in each language to avoid problems.  In English, it
  6257.     is always sufficient to provide the first three letters.  In French,
  6258.     however, you need at least four letters, to distinguish between "Juin"
  6259.     (June) and "Juillet" (July).
  6260.     
  6261.     Parse-O-Matic can use only one POMDATE.CFG file at a time, so the MONTHNUM
  6262.     command can not be used to translate month names from one language to
  6263.     another.  You can, however, accomplish the same thing with the LOOKUP
  6264.     command.
  6265.     
  6266.  
  6267.  
  6268.  
  6269.  
  6270.  
  6271.  
  6272.  
  6273.                                                                             105
  6274.                                 --------------------
  6275.                                 The ZERODATE Command
  6276.                                 --------------------
  6277.     
  6278.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  6279.     
  6280.     FORMAT:        ZERODATE value1 value2 value3
  6281.     
  6282.     PURPOSE:       Specifies "day zero" for the date serial number used by the
  6283.                    MAKETEXT command when it uses the DATE predefined data type.
  6284.     
  6285.     PARAMETERS:    value1 is the year  (e.g. "1900")
  6286.                    value2 is the month (e.g. "12" for December)
  6287.                    value3 is the day   (e.g. "5")
  6288.     
  6289.     NUMERICS:      Tabs, spaces and commas are stripped from value1, 2 and 3
  6290.     
  6291.     DEFAULTS:      If the ZERODATE command is omitted, the zero date is assumed
  6292.                    to be Jan. 1, 1753 (equivalent to ZERODATE "1753" "1" "1").
  6293.     
  6294.     SEE ALSO:      "The MakeText Command" and "Predefined Data Types"
  6295.     
  6296.     A "date serial number" is a common method of representing a date in a data
  6297.     file.  It works by counting the number of days since a given date, taking
  6298.     into account the extra days for leap years.
  6299.     
  6300.     Leap years occur in every year that is divisible by four, with the
  6301.     exception of century years -- unless they are divisible by 400. Thus, 1900
  6302.     is not a leap year, but 2000 is.
  6303.     
  6304.     The ZERODATE command specifies "Day 0".  For example, if you specify
  6305.     ZERODATE "1918" "11" "11" (November 11, 1918), you get the following:
  6306.     
  6307.                      DATE               DATE SERIAL NUMBER
  6308.                      -----------------  ------------------
  6309.                      November  9, 1918          -2
  6310.                      November 10, 1918          -1
  6311.                      November 11, 1918           0
  6312.                      November 12, 1918           1
  6313.                      November 13, 1918           2
  6314.     
  6315.     ... and so on.  Most programs set the zero date far enough back that
  6316.     negative numbers are not encountered in normal usage.
  6317.     
  6318.     ZERODATE will not accept a starting year before "1753", which was the first
  6319.     full year that most of the Western world started using the Gregorian
  6320.     calendar.
  6321.     
  6322.     
  6323.     
  6324.  
  6325.  
  6326.  
  6327.  
  6328.                                                                             106
  6329.     ============================================================================
  6330.                                 CALCULATION COMMANDS
  6331.     ============================================================================
  6332.     
  6333.                                   ----------------
  6334.                                   The CALC Command
  6335.                                   ----------------
  6336.     
  6337.     FORMAT:        CALC var1 value1 operation value2
  6338.     
  6339.     PURPOSE:       The CALC command performs an integer arithmetic operation on
  6340.                    the two values and assigns the answer to var1.
  6341.     
  6342.     NUMERICS:      Tabs, spaces and commas are stripped from value1 and value2
  6343.     
  6344.     ALTERNATIVES:  The CALCREAL command
  6345.     
  6346.     SEE ALSO:      "Inline Incrementing and Decrementing"
  6347.     
  6348.     Integer arithmetic refers to whole numbers.  1, 10 and 10000 are integers,
  6349.     while 2.0, 3.14159 and 98.5 are not.
  6350.     
  6351.     Let's say your input file looks like this:
  6352.     
  6353.     DESCRIPTION      UNITS SOLD    UNIT PRICE
  6354.     ---------------- ----------    ----------
  6355.     Dog collar               15    $     3.00
  6356.     Cat collar               25    $     2.50
  6357.     Cat caller                3    $     7.25
  6358.     Birdie num-nums       1,305    $     6.25
  6359.     ---------------- ----------    ----------
  6360.     End of Data
  6361.     :                :        :     :       :
  6362.     :                :        :     :       :    (Column positions)
  6363.     1               18       27    33      41
  6364.     
  6365.     You can find out the total number of units sold (of all types) with the
  6366.     following POM file:
  6367.     
  6368.     IGNORE $FLINE[1 7] = "DESCRIP"
  6369.     IGNORE $FLINE[1 7] = "-------"
  6370.     BEGIN $FLINE = "End of Data"
  6371.       OUTEND |Total units sold = {units}
  6372.     ELSE
  6373.       CALC units = units "+" $FLINE[18 27]
  6374.     END
  6375.     
  6376.     As you can see from the example, all spaces and commas are stripped from
  6377.     the number.  Tab characters (ASCII 09) are also stripped.
  6378.     
  6379.     You will also notice that CALC can not be used for the prices, since they
  6380.     are not integer data.  To add up the prices, you must use the CALCREAL
  6381.     command (see "The CalcReal Command").
  6382.  
  6383.                                                                             107
  6384.     Note in particular that the operation ("+" in this case) is in quotes.  If
  6385.     you omit the quotes, Parse-O-Matic will report an error.
  6386.     
  6387.     The following operations can be performed with CALC:
  6388.     
  6389.             SYMBOL     DESCRIPTION
  6390.             ---------  --------------------------------------------
  6391.             "+"        value1 plus value2
  6392.             "-"        value1 minus value2
  6393.             "*"        value1 times value2
  6394.             "/"        value1 divided by value2 (remainder ignored)
  6395.             "HIGHEST"  the larger number (value1 or value2)
  6396.             "LOWEST"   the smaller number (value1 or value2)
  6397.     
  6398.     Here are some more examples of the CALC command:
  6399.     
  6400.                    COMMAND                           ANSWER
  6401.                    --------------------------------  ------
  6402.                    CALC answer = "12" "/" "4"           "3"
  6403.                    CALC answer = "12" "HIGHEST" "4"    "12"
  6404.                    CALC answer = "12" "LOWEST"  "4"     "4"
  6405.                    CALC answer = "12" "-" "4"           "8"
  6406.                    CALC answer = "12" "+" "4"          "16"
  6407.                    CALC answer = "12" "*" "4"          "48"
  6408.     
  6409.     CALC can handle numbers between -2,147,483,648 and 2,147,483,647.
  6410.     
  6411.                                 --------------------
  6412.                                 The CALCREAL Command
  6413.                                 --------------------
  6414.     
  6415.     FORMAT:        CALCREAL var1 value1 operation value2 [fixed-decimals]
  6416.     
  6417.     PURPOSE:       CALCREAL works the same way as CALC, except that it handles
  6418.                    decimal numbers.
  6419.     
  6420.     NUMERICS:      Tabs, spaces and commas are stripped from value1, value2,
  6421.                    and the "fixed-decimals" value
  6422.     
  6423.     ALTERNATIVES:  The CALC command
  6424.     
  6425.     SEE ALSO:      "The Rounding Command"
  6426.     
  6427.  
  6428.  
  6429.  
  6430.  
  6431.  
  6432.  
  6433.  
  6434.  
  6435.  
  6436.  
  6437.  
  6438.                                                                             108
  6439.     Using the sample data given in the CALC section, you could write the
  6440.     following POM file:
  6441.     
  6442.     IGNORE $FLINE[1 7] = "DESCRIP"
  6443.     IGNORE $FLINE[1 7] = "-------"
  6444.     BEGIN $FLINE = "End of Data"
  6445.       OUTEND |Total units sold = {units}
  6446.       OUTEND |Total value sold = {value}
  6447.     ELSE
  6448.       CALC     units = units "+" $FLINE[18 27]
  6449.       CALCREAL value = value "+" $FLINE[33 41]
  6450.     END
  6451.     
  6452.     CALCREAL can handle values +/- 99,999,999,999, but its accuracy decreases
  6453.     when you are dealing with large numbers, as approximated below:
  6454.     
  6455.     Accurate to 1 decimal place  between +/- 9,999,999,999
  6456.     Accurate to 2 decimal places between +/-   999,999,999
  6457.     Accurate to 3 decimal places between +/-    99,999,999
  6458.     Accurate to 4 decimal places between +/-     9,999,999
  6459.     Accurate to 5 decimal places between +/-       999,999
  6460.     
  6461.     You can specify a fixed number of decimal positions in the answer by using
  6462.     the optional "fixed-decimals" value.  For example:
  6463.     
  6464.     SET z = "3.14159"
  6465.     CALCREAL x = z "+" "0" "2"      <-- This sets x to "3.14"
  6466.     CALCREAL x = z "+" "0" "4"      <-- This sets x to "3.1415"
  6467.     
  6468.     You will notice, in the second example, that no "rounding" takes place.
  6469.     The number is simply truncated at the requested decimal position.
  6470.     
  6471.     Here are some more examples of the CALCREAL command:
  6472.     
  6473.            COMMAND                                           ANSWER
  6474.            -----------------------------------------------  --------
  6475.            CALCREAL answer = "12.0"  "*"        "4.0"  "2"   "48.00"
  6476.            CALCREAL answer = "12.0"  "HIGHEST"  "4.0"  "2"   "12.00"
  6477.            CALCREAL answer =   "12"  "LOWEST      "4"  "1"     "4.0"
  6478.            CALCREAL answer =   "12"  "-"          "4"  "3"   "8.000"
  6479.            CALCREAL answer =   "12"  "+"          "4"  "1"    "16.0"
  6480.            CALCREAL answer =    "7"  "/"          "2"  "2"    "3.50"
  6481.            CALCREAL answer =    "7"  "/"          "2"          "3.5"
  6482.            CALCREAL answer =    "7"  "*"          "2"         "14.0"
  6483.     
  6484.     As shown in the examples, if you do not use the optional fixed-decimal
  6485.     value, calculations are in "floating point".  That is to say, the answer
  6486.     has as many decimal places as necessary.  (Bear in mind the accuracy
  6487.     restrictions mentioned earlier.)  Trailing zeros are removed, unless there
  6488.     are no digits after the decimal point, in which case a 0 is added.
  6489.     
  6490.  
  6491.  
  6492.  
  6493.                                                                             109
  6494.                                 --------------------
  6495.                                 The ROUNDING Command
  6496.                                 --------------------
  6497.     
  6498.     FORMAT:        ROUNDING "Y" or ROUNDING "N"
  6499.     
  6500.     PURPOSE:       Controls rounding of answers given by the CALCREAL command
  6501.                    when it is in "fixed-decimal" mode.
  6502.     
  6503.     PARAMETERS:    ROUNDING "Y" turns on rounding (the default)
  6504.                    ROUNDING "N" turns off rounding
  6505.     
  6506.     ALTERNATIVES:  The CALCREAL command can be used in "floating point" mode,
  6507.                    and you can perform rounding and truncation operations
  6508.                    yourself, within the POM file.
  6509.     
  6510.     Due to the way that real numbers (as opposed to integers) are calculated in
  6511.     binary, CALCREAL can sometimes return unexpected results.  For example:
  6512.     
  6513.     CALCREAL x = "400.00" "-" "390.60"
  6514.     
  6515.     produces the answer "9.399999" rather than the expected answer of "9.4".
  6516.     
  6517.     This discrepancy is due to the nature of real-mode calculations in binary
  6518.     (i.e. inside the computer). The answer is actually very close indeed to the
  6519.     correct answer, yet it could cause problems if you specify the actual number
  6520.     of digits of precision ("fixed-decimals" mode instead of "floating point"
  6521.     mode).  For example:
  6522.     
  6523.     ROUNDING "N"                              <-- This is explained later
  6524.     CALCREAL x = "400.00" "-" "390.60" "2"    <-- 2 digits of precision
  6525.     
  6526.     This sets the x variable to "3.39", which is clearly wrong.  What has
  6527.     happened is that the remaining digits of the floating-point answer were
  6528.     simply truncated (i.e. removed).
  6529.     
  6530.     Normally, Parse-O-Matic's built-in rounding will add a small value
  6531.     appropriate to the number of digits of fixed-decimal precision you have
  6532.     specified:
  6533.     
  6534.                      PRECISION   SAMPLE NUMBER   ROUNDING VALUE
  6535.                      ---------   -------------   --------------
  6536.                          1           9.9            + 0.05
  6537.                          2           9.99           + 0.005
  6538.                          3           9.999          + 0.0005
  6539.     
  6540.     ... and so on.  Thus, CALCREAL "400.00" "-" "390.60" "2" first generates the
  6541.     floating-point answer "9.3999999999", adds "0.005", yielding "9.4049999999".
  6542.     This is then truncated to two digits, yielding "9.40", which is the correct
  6543.     answer.
  6544.     
  6545.  
  6546.  
  6547.  
  6548.                                                                             110
  6549.     You can turn this rounding behavior off with the following command:
  6550.     
  6551.     ROUNDING "N"
  6552.     
  6553.     You can turn it back on with this command:
  6554.     
  6555.     ROUNDING "Y"
  6556.     
  6557.     By default, rounding is enabled, so unless you explicitly turn it off, there
  6558.     is no need to use the ROUNDING "Y" command.
  6559.     
  6560.     No rounding is performed when CALCREAL is used in "floating-point" mode.
  6561.     
  6562.                                 --------------------
  6563.                                 The CALCBITS Command
  6564.                                 --------------------
  6565.     
  6566.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  6567.     
  6568.     FORMAT:        CALCBITS var1 value1 operation value2
  6569.     
  6570.     PURPOSE:       CALCBITS performs logical operations
  6571.     
  6572.     SEE ALSO:      "The MakeData Command"
  6573.     
  6574.     The CALCBITS command performs "bit-wise" operations on single bytes.  The
  6575.     following operations can be performed with CALCBITS:
  6576.     
  6577.                   SYMBOL     DESCRIPTION
  6578.                   ---------  ---------------------------------
  6579.                   "AND"      value1 AND value2
  6580.                   "OR"       value1 OR  value2
  6581.                   "XOR"      value1 XOR value2
  6582.                   "SHR"      Shift value1 right by value2 bits
  6583.                   "SHL"      Shift value1 left  by value2 bits
  6584.     
  6585.     Let us say you want to strip the high bit from all of the bytes in an input
  6586.     file.  You could accomplish this with the following POM file:
  6587.     
  6588.     CHOP     1-1                    <-- Read the input file one byte at a time
  6589.     CALCBITS z $FLINE "AND" $7F     <-- Remove the high bit from the byte
  6590.     OUT      |{z}                   <-- Send the result to the output file
  6591.     
  6592.     Note that because we are reading the file one byte at a time, $FLINE is
  6593.     always one byte long.  Parse-O-Matic will terminate with an error message
  6594.     if you attempt to use CALCBITS with a value longer than one byte.  Thus,
  6595.     assuming the variable xyz contains "ABCDEF", the following line is valid:
  6596.     
  6597.     CALCBITS answer = xyz[3] "AND" $7F
  6598.     
  6599.  
  6600.  
  6601.  
  6602.  
  6603.                                                                             111
  6604.     However, the following line would not be permitted because it refers to
  6605.     more than one byte:
  6606.     
  6607.     CALCBITS answer = xyz[3 4] "AND" $7F
  6608.     
  6609.     Here are some more examples of the CALCBITS command:
  6610.     
  6611.     COMMAND                           ANSWER   COMMENTS
  6612.     -------------------------------   ------   ------------------------------
  6613.     CALCBITS answer = $FF "AND" $7F     $7F
  6614.     CALCBITS answer = "9" "AND" $39     $39    $39 is the character "9"
  6615.     CALCBITS answer = $F0 "OR"  $0F     $FF
  6616.     CALCBITS answer = $7F "XOR" $08     $77
  6617.     CALCBITS answer = $80 "SHR" $01     $40    $80 = 10000000; $40 = 01000000
  6618.     CALCBITS answer = $01 "SHR" $01     $00    $01 = 00000001; $00 = 00000000
  6619.     CALCBITS answer = $01 "SHL" $01     $02    $01 = 00000001; $02 = 00000010
  6620.     CALCBITS answer = $80 "SHL" $01     $00    $80 = 10000000; $00 = 00000000
  6621.     
  6622.     In most of these examples, we use hex notation (e.g. $01), but you can also
  6623.     use single characters (e.g. "3" which is equivalent to $33) or decimal
  6624.     notation (e.g. #64 which is equivalent to $40).  However, you should always
  6625.     bear in mind that you are working with the underlying bit pattern.  The
  6626.     following lines are NOT equivalent:
  6627.     
  6628.     CALCBITS answer = $7F "SHL" $01         <-- Shifts left one bit
  6629.     CALCBITS answer = $7F "SHL" "1"         <-- This is not the same!
  6630.     
  6631.     The second line interprets "1" as hex $31 (decimal 49).  There is obviously
  6632.     no point in shifting an eight-bit byte 49 positions to the left.
  6633.     
  6634.     
  6635.     
  6636.     
  6637.     
  6638.  
  6639.  
  6640.  
  6641.  
  6642.  
  6643.  
  6644.  
  6645.  
  6646.  
  6647.  
  6648.  
  6649.  
  6650.  
  6651.  
  6652.  
  6653.  
  6654.  
  6655.  
  6656.  
  6657.  
  6658.                                                                             112
  6659.     ============================================================================
  6660.                                 INPUT PREPROCESSORS
  6661.     ============================================================================
  6662.     
  6663.                                  -----------------
  6664.                                  The SPLIT Command
  6665.                                  -----------------
  6666.     
  6667.     FORMAT:        SPLIT from-position to-position [,from-pos'n to-pos'n] [...]
  6668.     
  6669.     SEE ALSO:      "The Leftover Technique"
  6670.     
  6671.     IMPORTANT:     This command is analyzed at compile time, which means it can
  6672.                    not be used conditionally (i.e. in a BEGIN/END block).
  6673.     
  6674.     The maximum length of an input line from a text file is 255 characters.  If
  6675.     your input file is wider than that, you must break up the file into
  6676.     manageable chunks, using the SPLIT command.  This command lets you specify
  6677.     the way in which each input line is broken up so that it will look like
  6678.     several SEPARATE lines.
  6679.     
  6680.     For example, if your input lines were up to 300 characters wide, you could
  6681.     specify:
  6682.     
  6683.     SPLIT 1 255, 256 300
  6684.     
  6685.     This breaks up each line as if it was two lines.  (If some of the lines are
  6686.     less than 256 characters, they will still be treated as two lines, although
  6687.     the second line will be null (i.e. empty).)
  6688.     
  6689.     You can specify up to 130 splits (use multiple SPLIT commands if
  6690.     necessary).  With SPLIT, Parse-O-Matic can handle large input records,
  6691.     up to a maximum total length of 32767 characters.
  6692.     
  6693.     The best way of handling SPLIT or CHOPped files is to use a combination of
  6694.     the $SPLIT variable (explained in more detail later) and BEGIN/END.  For
  6695.     example:
  6696.     
  6697.     SPLIT 1 250, 251 300
  6698.     BEGIN $SPLIT = "1"
  6699.       SET a = $FLINE[ 1 10]
  6700.       SET b = $FLINE[11 20]
  6701.     END
  6702.     BEGIN $SPLIT = "2"
  6703.       SET x = $FLINE[ 1 10]
  6704.       SET y = $FLINE[11 20]
  6705.       OUTEND |{a} {b} {x} {y}
  6706.     END
  6707.     
  6708.     This outputs the data which appears (in the input file) in columns 1-10,
  6709.     11-20, 251-260 and 261-280.
  6710.     
  6711.  
  6712.  
  6713.                                                                             113
  6714.     ------------------------------
  6715.     Indicating Actual Input Length
  6716.     ------------------------------
  6717.     
  6718.     The final split must indicate the maximum length of the line.  Thus, if you
  6719.     have a text file with a maximum line length of 275, you still have to
  6720.     indicate this, even if you are only interested in the first 100 characters:
  6721.     
  6722.     SPLIT 1-100, 101-275
  6723.     
  6724.     You could use IGNORE $SPLIT = "2" to get rid of the additional text lines.
  6725.     
  6726.     ---------------------
  6727.     Non-Contiguous Splits
  6728.     ---------------------
  6729.     
  6730.     Your splits do not have to be contiguous.  For example, the following SPLIT
  6731.     command is legal:
  6732.     
  6733.     SPLIT 5 39, 41 100, 247 285
  6734.     
  6735.     The first four characters of each split would be ignored, so your first
  6736.     split would contain only the characters at positions 5 to 39 of the line.
  6737.     Similarly, the second split would contain the 41st through 100th character,
  6738.     and the third split would contain the 247th through 285th character.
  6739.     
  6740.                                   ----------------
  6741.                                   The CHOP Command
  6742.                                   ----------------
  6743.     
  6744.     FORMAT:        CHOP from-position to-position [,from-pos'n to-pos'n] [...]
  6745.                    CHOP 0
  6746.     
  6747.     PURPOSE:       Controls the number of bytes Parse-O-Matic will read from
  6748.                    the input file each time it processes the POM file.
  6749.     
  6750.     SEE ALSO:      "The Get Command"
  6751.     
  6752.     IMPORTANT:     This command is analyzed at compile time, which means it can
  6753.                    not be used conditionally (i.e. in a BEGIN/END block).
  6754.     
  6755.     The CHOP command works the same way as the SPLIT command, with one
  6756.     exception:  it informs Parse-O-Matic that the input is a fixed-record-
  6757.     length file. In other words, it means that the input records are
  6758.     distinguished by having a particular (and exact) length, rather than being
  6759.     separated by end-of-line characters (Carriage Return, Linefeed) as is the
  6760.     case for a standard text file.
  6761.     
  6762.     Thus, if you have an input file containing fixed-length records, each of
  6763.     which is 200 characters wide, you could specify it like this:
  6764.     
  6765.     CHOP 1 200
  6766.     
  6767.  
  6768.                                                                             114
  6769.     If the input record is more than 255 characters, you must break it up into
  6770.     smaller chunks.  For example, if the input record was 300 characters wide,
  6771.     you could break it up like this:
  6772.     
  6773.     CHOP 1 250, 251 300
  6774.     
  6775.     By using CHOP, Parse-O-Matic can handle input records up to 32767
  6776.     characters wide.  You can use the $SPLIT variable to manage your use of
  6777.     CHOP.  See the example in the section describing the SPLIT command.
  6778.     
  6779.     --------------
  6780.     Manual Reading
  6781.     --------------
  6782.     
  6783.     There is a special form of the CHOP command, which looks like this:
  6784.     
  6785.     CHOP 0
  6786.     
  6787.     This tells Parse-O-Matic that you will handle all file reading yourself. In
  6788.     such case, $FLINE is always null.  The only way to get data from the input
  6789.     file is with the GET command.
  6790.     
  6791.     When you use CHOP 0 for manual reading, the MINLEN and READNEXT commands
  6792.     have no meaning.  If you place them in the POM file, they are ignored.
  6793.     
  6794.     
  6795.     
  6796.  
  6797.  
  6798.  
  6799.  
  6800.  
  6801.  
  6802.  
  6803.  
  6804.  
  6805.  
  6806.  
  6807.  
  6808.  
  6809.  
  6810.  
  6811.  
  6812.  
  6813.  
  6814.  
  6815.  
  6816.  
  6817.  
  6818.  
  6819.  
  6820.  
  6821.  
  6822.  
  6823.                                                                             115
  6824.     ============================================================================
  6825.                                   LOOKUP COMMANDS
  6826.     ============================================================================
  6827.     
  6828.                                  ------------------
  6829.                                  The LOOKUP Command
  6830.                                  ------------------
  6831.     
  6832.     FORMAT:        LOOKUP var1 value1
  6833.     
  6834.     PURPOSE:       The LOOKUP command searches for value1 in a text file (the
  6835.                    name of which is specified either by the LOOKFILE command or
  6836.                    the /L startup parameter). When POM finds it, it sets var1
  6837.                    to another value found on the same line.
  6838.     
  6839.     ALTERNATIVES:  The REMAP command
  6840.     
  6841.     Let us suppose you created a text file, named NAMES.TBL, like this:
  6842.     
  6843.     R. REAGAN        Ronald Reagan
  6844.     D. EISENHOWER    Dwight Eisenhower
  6845.     G. BUSH          George Bush
  6846.     B. CLINTON       Bill Clinton
  6847.     :                :
  6848.     Column 1         Column 18
  6849.     
  6850.     This file can be used to look up a name, as in this POM file:
  6851.     
  6852.     LOOKFILE "NAMES.TBL"
  6853.     LOOKCOLS "1" "17" "18" "34"
  6854.     SET      oldname = $FLINE[21 37]
  6855.     TRIM     oldname "R" " "
  6856.     LOOKUP   newname = oldname
  6857.     OUTEND   |{oldname} {newname}
  6858.     
  6859.     The LOOKFILE command specifies the name of the look-up file.  The LOOKCOLS
  6860.     command specifies the starting and end columns for both the "text-to-look-
  6861.     for" field (known as the key field) and the "text-to-get" field (known as
  6862.     the data field).
  6863.     
  6864.     The LOOKUP command will look for oldname in NAMES.TBL.  If oldname is set
  6865.     to "G. BUSH", LOOKUP sets newname to "George Bush".  If, however, oldname
  6866.     is set to "G. WASHINGTON", which doesn't appear in NAMES.TBL, newname
  6867.     is set to "" (that is to say, an empty string).
  6868.     
  6869.  
  6870.  
  6871.  
  6872.  
  6873.  
  6874.  
  6875.  
  6876.  
  6877.  
  6878.                                                                             116
  6879.     -------------
  6880.     Search Method
  6881.     -------------
  6882.     
  6883.     When searching for the key field, LOOKUP compares text according to the
  6884.     length of the string you are looking for.  If your LOOKUP file looks like
  6885.     this:
  6886.     
  6887.         ABCDEF    456
  6888.         ABC       678
  6889.         XYZABC    345
  6890.         XYZ       123
  6891.     
  6892.     then the command LOOKUP x = "XYZ" would match on "XYZABC".  If this search
  6893.     procedure is a problem for you, there are two ways you can deal with it:
  6894.     
  6895.     1)  Pad your search strings before searching, as in this example:
  6896.     
  6897.         PAD     search "R" " " "6"
  6898.         LOOKUP  x = search
  6899.     
  6900.         If the search variable was original set to "XYZ", the PAD command
  6901.         would set it to "XYZ   ", which would not match XYZABC.
  6902.     
  6903.     2)  Put the shorter key fields in the lookup file ahead of the longer
  6904.         ones (of which they are a sub-string), as in this example:
  6905.     
  6906.         ABC       678
  6907.         ABCDEF    456
  6908.         XYZ       123
  6909.         XYZABC    345
  6910.     
  6911.         It is worth pointing out that this look-up file is sorted in
  6912.         ASCII order (whereas the example given earlier was not).  A sorted
  6913.         file can be more efficient, as explained in "The LookSpec Command".
  6914.     
  6915.     -----------
  6916.     Limitations
  6917.     -----------
  6918.     
  6919.     There is no limit to the number of lines that you can put in a look-up
  6920.     file.  However, the more lines there are, the longer it will take to
  6921.     process (because there is more to search).  The maximum length of a line
  6922.     in a look-up file is 255 characters.
  6923.     
  6924.  
  6925.  
  6926.  
  6927.  
  6928.  
  6929.  
  6930.  
  6931.  
  6932.  
  6933.                                                                             117
  6934.     -----------------------
  6935.     Null Lines and Comments
  6936.     -----------------------
  6937.     
  6938.     In the look-up file, null (empty) lines are ignored.  You can also include
  6939.     comments in the file by starting the line with a semi-colon:
  6940.     
  6941.     ; Some of the Presidents of the United States
  6942.     R. REAGAN        Ronald Reagan
  6943.     D. EISENHOWER    Dwight Eisenhower
  6944.     G. BUSH          George Bush
  6945.     
  6946.     The LOOKUP command can be used for more than just names, of course.  You
  6947.     could use it to look up prices, phone numbers, addresses and so on.
  6948.     
  6949.     ----------------
  6950.     Multiple Columns
  6951.     ----------------
  6952.     
  6953.     You can use the same lookup file to find different items that are related
  6954.     to the same key field.  For example, let's say you have created a lookup
  6955.     file, named EMPLOYEE.TBL, which looks like this:
  6956.     
  6957.     ; EMPLOYEE#   NAME           PHONE
  6958.       00001       John Smith     555-1212
  6959.       00002       Mary Jones     555-2121
  6960.       00003       Fred Johnson   555-1122
  6961.     
  6962.     You could look up an employee's name and phone number as follows:
  6963.     
  6964.     LOOKFILE "EMPLOYEE.TBL"
  6965.     LOOKCOLS "3" "7" "15" "37"
  6966.     LOOKSPEC "N" "Y" "N"
  6967.     LOOKUP   empdata = "00002"
  6968.     SET      name  = empdata[ 1 12]
  6969.     SET      phone = empdata[16 23]
  6970.     TRIM     name  "B" " "
  6971.     TRIM     phone "B" " "
  6972.     
  6973.     You could, of course, specify a different LOOKCOLS prior to each LOOKUP,
  6974.     but that would mean reading the disk twice.  It most cases, it is faster
  6975.     to obtain the data all at once, then extract it.
  6976.     
  6977.  
  6978.  
  6979.  
  6980.  
  6981.  
  6982.  
  6983.  
  6984.  
  6985.  
  6986.  
  6987.  
  6988.                                                                             118
  6989.     -------------------
  6990.     LOOKUP Versus REMAP
  6991.     -------------------
  6992.     
  6993.     If you have only a few thousand bytes of lookup data, you might be able to
  6994.     use the REMAP command instead of LOOKUP.  However, you can not simply
  6995.     replace LOOKFILE and LOOKUP with MAPFILE and REMAP.  REMAP does not return
  6996.     a null value if it can not find the item being sought, so you will have to
  6997.     change your POM file to compare the original string with the revised
  6998.     string, in order to see if it has changed (i.e. it was found).  Even with
  6999.     this test, REMAP might "fool you" if it finds a partial match.
  7000.     
  7001.     If you are processing a lot of input data, using REMAP may speed up
  7002.     processing, since REMAP works in RAM memory, while LOOKUP reads the disk.
  7003.     However, if your disk uses "caching", the performance improvement may be
  7004.     negligible.
  7005.     
  7006.                                 --------------------
  7007.                                 The LOOKFILE Command
  7008.                                 --------------------
  7009.     
  7010.     FORMAT:        LOOKFILE value1
  7011.     
  7012.     PURPOSE:       The LOOKFILE command specifies the name of the look-up file
  7013.                    for the next LOOKUP command.
  7014.     
  7015.     SEE ALSO:      "How Parse-O-Matic Searches for a File"
  7016.     
  7017.     LOOKFILE lets you use several look-up files in one POM file. For example:
  7018.     
  7019.     SET      name = $FLINE[1 20]
  7020.     ;   Look up the name
  7021.     LOOKFILE "NAMES.TBL"
  7022.     LOOKCOLS "1" "25" "30" "50"
  7023.     LOOKUP   fullname = name
  7024.     ;   Look up phone number
  7025.     LOOKFILE "PHONE.TBL"
  7026.     LOOKCOLS "1" "25" "30" "40"
  7027.     LOOKUP   phone = name
  7028.     ;   Output result
  7029.     OUTEND   |{name} {fullname} {newname}
  7030.     
  7031.     If you only have one look-up file, you may omit the LOOKFILE command and
  7032.     specify the file name on the command line, using the /L parameter.  For
  7033.     example, you could write a POM file like this:
  7034.     
  7035.     SET      name = $FLINE[1 20]
  7036.     ;   Look up the name
  7037.     LOOKCOLS "1" "25" "30" "50"
  7038.     LOOKUP   fullname = name
  7039.     ;   Output result
  7040.     OUTEND   |{name} {fullname}
  7041.     
  7042.  
  7043.                                                                             119
  7044.     Your POM command could then look like this:
  7045.     
  7046.     POM MYPOM.POM INPUT.TXT OUTPUT.TXT /LC:\MYFILES\NAMES.TBL
  7047.     
  7048.     This technique allows you to use several different look-up files with the
  7049.     same POM file, simply by changing the command line.  (The method by which
  7050.     Parse-O-Matic finds the file is discussed in the section "How Parse-O-Matic
  7051.     Searches for a File".)
  7052.     
  7053.     The longest line allowed in a look-up file is 255 characters long.
  7054.     
  7055.     If you specify a null look-up file name (e.g. LOOKFILE ""), Parse-O-Matic
  7056.     closes the current look-up file (if one is open).  This is necessary if you
  7057.     wish to delete the file, using the ERASE command.
  7058.     
  7059.                                 --------------------
  7060.                                 The LOOKCOLS Command
  7061.                                 --------------------
  7062.     
  7063.     FORMAT:        LOOKCOLS value1 value2 value3 value4
  7064.     
  7065.     PURPOSE:       The LOOKCOLS command specifies the starting and ending
  7066.                    columns for the key and data fields in a look-up file (see
  7067.                    the explanation of the LOOKUP command for an overview of
  7068.                    look-up files).
  7069.     
  7070.     PARAMETERS:    value1 specifies the starting column for the key  field
  7071.                    value2 specified the  ending  column for the key  field
  7072.                    value3 specifies the starting column for the data field
  7073.                    value4 specified the  ending  column for the data field
  7074.     
  7075.     NUMERICS:      Tabs, spaces and commas are stripped from value1, 2, 3 and 4
  7076.     
  7077.     You can specify a null value to indicate "same as last time".  For example:
  7078.     
  7079.     SET name = $FLINE[1 20]
  7080.     LOOKFILE "NAMES.TBL"
  7081.     LOOKCOLS "1" "25" "30" "50"
  7082.     LOOKUP   fullname = name
  7083.     LOOKFILE "PHONE.TBL"
  7084.     LOOKCOLS "" "" "" "40"
  7085.     LOOKUP   phonenum = name
  7086.     OUTEND   |{name} {fullname} {phonenum}
  7087.     
  7088.     The second LOOKCOLS command uses the same numbers for the first three
  7089.     values that the first LOOKCOLS command used.
  7090.     
  7091.  
  7092.  
  7093.  
  7094.  
  7095.  
  7096.  
  7097.  
  7098.                                                                             120
  7099.     If you do not specify a LOOKCOLS command, the default values are:
  7100.     
  7101.     Key Field:   Starting column  =   1
  7102.                  Ending column    =  10
  7103.     Data Field:  Starting column  =  12
  7104.                  Ending column    = 255
  7105.     
  7106.     This is equivalent to LOOKCOLS "1" "10" "12" "255".
  7107.     
  7108.                                 --------------------
  7109.                                 The LOOKSPEC Command
  7110.                                 --------------------
  7111.     
  7112.     FORMAT:        LOOKSPEC value1 value2 value3
  7113.     
  7114.     PURPOSE:       The LOOKSPEC command configures the way the next LOOKUP
  7115.                    command will work.
  7116.     
  7117.     PARAMETERS:    value1 = Trim           ("Y" or "N" -- default "Y")
  7118.                    value2 = Sorted         ("Y" or "N" -- default "N")
  7119.                    value3 = Case-sensitive ("Y" or "N" -- default "N")
  7120.     
  7121.     The Trim setting specifies whether or not the data field should have spaces
  7122.     stripped off both ends.
  7123.     
  7124.     The Sorted setting specifies whether or not the look-up file is sorted by
  7125.     the key field.  A sorted file is much faster than an unsorted file.  This
  7126.     is especially noticeable if you have a large look-up file and a lot of
  7127.     input to process.
  7128.     
  7129.     The Case-sensitive setting specifies whether or not LOOKUP should distin-
  7130.     guish between upper and lower case when searching.  The default setting is
  7131.     "N" (No), so that LOOKUP would find "John Smith", even if it appeared in
  7132.     the look-up file as "JOHN SMITH".  It is usually safest to set Case-
  7133.     sensitivity to "N", but if you set it to "Y", searching is slightly faster.
  7134.     
  7135.     You can specify a null value to indicate "same as last time".  For example:
  7136.     
  7137.     SET name = $FLINE[1 20]
  7138.     LOOKFILE "DATA.TBL"
  7139.     LOOKCOLS "1" "25" "30" "50"
  7140.     LOOKSPEC "Y" "Y" "Y"
  7141.     LOOKUP   fullname = name
  7142.     LOOKCOLS "" "" "60" "70"
  7143.     LOOKSPEC "N" "" ""
  7144.     LOOKUP   phonenum = name
  7145.     OUTEND   |{name} {fullname} {phonenum}
  7146.     
  7147.     The second LOOKSPEC command uses the same settings for Sorted and Case-
  7148.     sensitivity as the first one, but specifies a different Trim setting.
  7149.     
  7150.     
  7151.     
  7152.  
  7153.                                                                             121
  7154.     ============================================================================
  7155.                                   DATA CONVERTERS
  7156.     ============================================================================
  7157.     
  7158.                                 --------------------
  7159.                                 The MAKEDATA Command
  7160.                                 --------------------
  7161.     
  7162.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  7163.     
  7164.     FORMAT:        MAKEDATA var1 value1 value2
  7165.     
  7166.     PURPOSE:       MAKEDATA converts text data into a binary format.
  7167.     
  7168.     PARAMETERS:    var1     is the variable being set
  7169.                    value1   is the text data you want to convert
  7170.                    value2   is the predefined data type you want to create
  7171.     
  7172.     NUMERICS:      Tabs, spaces and commas are stripped from value1, if it is
  7173.                    numeric (as indicated by value2)
  7174.     
  7175.     SEE ALSO:      "Predefined Data Types" and "The CalcBits Command"
  7176.     
  7177.     When you are writing to a binary file (using the OUT command), you often
  7178.     need to convert text information to a binary representation.  MAKEDATA
  7179.     recognizes many standard data formats (see "Predefined Data Types").
  7180.     
  7181.     --------------------
  7182.     Creating Binary Data
  7183.     --------------------
  7184.     
  7185.     Let us say you have a four-line text file that looks like this:
  7186.     
  7187.      1234
  7188.      -456
  7189.        23
  7190.     90211
  7191.     
  7192.     Here is a POM file that reads the numbers from the file, then outputs them
  7193.     in binary format, as 16-bit signed integers:
  7194.     
  7195.     MAKEDATA z $FLINE "INTEGER"    <-- Convert the number to an integer
  7196.     OUT      |{z}                  <-- Send the integer to the output file
  7197.     
  7198.     We use OUT instead of OUTEND, since OUTEND would put an end-of-line
  7199.     (Carriage Return, Line Feed) after the data.
  7200.     
  7201.     If the POM file shown in the example was run with the input data shown,
  7202.     it would create an output file containing four integers.  In other words,
  7203.     the file would be eight bytes long (four integers of two bytes each).
  7204.     
  7205.  
  7206.  
  7207.  
  7208.                                                                             122
  7209.     ----------------
  7210.     Converting Dates
  7211.     ----------------
  7212.     
  7213.     In some files, a date serial number (see "The ZeroDate Command") might be
  7214.     represented by a numeric format such as INTEGER or LONGINT.  To write a
  7215.     date serial number to the output file, you must first convert the date with
  7216.     MAKEDATA, then use MAKEDATA again to convert the resulting number to the
  7217.     appropriate data type.
  7218.     
  7219.     The value1 part of the MAKEDATA must be in a precise format:
  7220.     
  7221.     "YYYY [M]M [D]D"               <-- Square brackets indicate optional digits
  7222.     
  7223.     That is to say:
  7224.     
  7225.     1) A four-digit year
  7226.     2) A space
  7227.     3) A one or two digit month (January = 1 or 01, December = 12)
  7228.     4) A space
  7229.     5) A one or two digit day of the month (e.g. 1 or 01 or 31)
  7230.     
  7231.     You can assemble the date string from various other data, using the
  7232.     DATE command.  Let us say you have a one-line text file that contains
  7233.     the date in Month-Day-Year format:
  7234.     
  7235.     01-01-2001
  7236.     
  7237.     You can read this file and output a date serial number as a long integer
  7238.     (LONGINT) with the following POM file:
  7239.     
  7240.     ZERODATE "2000" "1" "1"                <-- Set "day zero"
  7241.     SET      year  = $FLINE[7 10]          <-- Get the year
  7242.     SET      month = $FLINE[1  2]          <-- Get the month
  7243.     SET      day   = $FLINE[4  5]          <-- Get the day of the month
  7244.     DATE     x year month day "Y ?n ?d"    <-- Set x to "2001 01 01"
  7245.     MAKEDATA y x "DATE"                    <-- Set y to "366"
  7246.     MAKEDATA z y "LONGINT"                 <-- Set z to a long integer
  7247.     OUT      |{z}                          <-- Place it in the output file
  7248.     
  7249.     A typical problem with date data is that the year does not include
  7250.     the first two digits (e.g. you have "97" instead of "1997").  In
  7251.     such cases, your POM file has to make a decision as to which century
  7252.     the date belongs to.  Here is one way to handle this situation:
  7253.     
  7254.     BEGIN year #>= "50"
  7255.       CALC year = year + "1900"
  7256.     ELSE
  7257.       CALC year = year + "2000"
  7258.     END
  7259.     
  7260.  
  7261.  
  7262.  
  7263.                                                                             123
  7264.     This works around the problem as follows:
  7265.     
  7266.             Any year between     is placed in         Examples
  7267.             ----------------     ----------------     --------------
  7268.             "50" and "99"        the 20th century     "1950"  "1999"
  7269.             "00" and "49"        the 21st century     "2000"  "2049"
  7270.     
  7271.     You have to be careful when choosing the "cut-off date" (1950, in the
  7272.     example above).  You should make your decision only after studying your
  7273.     input data carefully.
  7274.     
  7275.     ------------------------
  7276.     Practical Considerations
  7277.     ------------------------
  7278.     
  7279.     The examples shown here assume that your input file contains only one kind
  7280.     of data.  In most cases, you will use the CHOP command to obtain complete
  7281.     data records of fixed length, then use SET to extract portions thereof.
  7282.     If you are reading a file with variable-length records, you can use CHOP 0
  7283.     (manual reading) and the GET command.
  7284.     
  7285.                                 --------------------
  7286.                                 The MAKETEXT Command
  7287.                                 --------------------
  7288.     
  7289.                    ** ADVANCED COMMAND FOR EXPERIENCED USERS **
  7290.     
  7291.     FORMAT:        MAKETEXT var1 value1 value2
  7292.     
  7293.     PURPOSE:       MAKETEXT converts binary data into text format.
  7294.     
  7295.     PARAMETERS:    var1     is the variable being set
  7296.                    value1   is the data you want to convert
  7297.                    value2   is the predefined data type of value1
  7298.     
  7299.     NOTES:         value1 is normally in binary (i.e. it looks like "garbage
  7300.                    characters" if you output it to a text file).  However, if
  7301.                    value2 specifies the DATE data type, value1 must be in text
  7302.                    form (e.g. "1234").  The reason for this difference is
  7303.                    described in the "Converting Dates" section below.
  7304.     
  7305.     SEE ALSO:      "Predefined Data Types"
  7306.     
  7307.     When reading a binary file (using the CHOP command), you often need to
  7308.     convert binary information to a text representation. MAKETEXT recognizes
  7309.     many standard data formats (see "Predefined Data Types").
  7310.     
  7311.  
  7312.  
  7313.  
  7314.  
  7315.  
  7316.  
  7317.  
  7318.                                                                             124
  7319.     ----------------------
  7320.     Converting Binary Data
  7321.     ----------------------
  7322.     
  7323.     Let us say you have a binary file that contains several WORD values
  7324.     (unsigned integers, each of which is 2 bytes long).  You can read and
  7325.     decode them with the following POM file:
  7326.     
  7327.     CHOP 1-2                            <-- Read the file two bytes at a time
  7328.     MAKETEXT x $FLINE "WORD"            <-- Convert the WORD to text format
  7329.     OUTEND   |{x}                       <-- Output the data to a text file
  7330.     
  7331.     ----------------
  7332.     Converting Dates
  7333.     ----------------
  7334.     
  7335.     MAKETEXT can convert a date serial number (see "The ZeroDate Command") to
  7336.     a formatted date.  Since there is no standard data format for date serial
  7337.     numbers, you must use MAKETEXT to convert the number into text form, and
  7338.     then use MAKETEXT again to format the date.
  7339.     
  7340.     Let us say you have a binary file that contains dates, represented as
  7341.     LONGINTs (4-byte signed integers).  You could convert them to dates with
  7342.     the following POM file:
  7343.     
  7344.     CHOP 1-4                     <-- Read 4 bytes at a time
  7345.     ZERODATE "1936" "1" "1"      <-- Set the "zero date"
  7346.     MAKETEXT x $FLINE "LONGINT"  <-- Convert the binary data to a text number
  7347.     MAKETEXT y x "DATE Y-M-?d"   <-- Convert to text date (e.g. "1998-JUL-01")
  7348.     OUTEND   |{y}                <-- Output the date to a text file
  7349.     
  7350.     ------------------------
  7351.     Practical Considerations
  7352.     ------------------------
  7353.     
  7354.     The examples shown here assume that your input file contains only one kind
  7355.     of data.  In most cases, you will use the CHOP command to obtain complete
  7356.     data records of fixed length, then use SET to extract portions thereof.
  7357.     If you are reading a file with variable-length records, you can use CHOP 0
  7358.     (manual reading) and the GET command.
  7359.     
  7360.     
  7361.     
  7362.  
  7363.  
  7364.  
  7365.  
  7366.  
  7367.  
  7368.  
  7369.  
  7370.  
  7371.  
  7372.  
  7373.                                                                             125
  7374.     ============================================================================
  7375.                                MISCELLANEOUS COMMANDS
  7376.     ============================================================================
  7377.     
  7378.                                  -----------------
  7379.                                  The ERASE Command
  7380.                                  -----------------
  7381.     
  7382.     FORMAT:        ERASE value1
  7383.     
  7384.     PURPOSE:       Deletes a file (if it exists).
  7385.     
  7386.     PARAMETERS:    value1 is the name of the file to be deleted
  7387.     
  7388.     SEE ALSO:      "Long File Names in Win95"
  7389.     
  7390.     Here is an example of the ERASE command:
  7391.     
  7392.     ERASE "C:\XYZ.TXT"
  7393.     
  7394.     This will delete the file C:\XYZ.TXT if it exists.  If it does not exist,
  7395.     nothing is done.
  7396.     
  7397.     You can not delete the current input file, output file, trace file or
  7398.     lookup file.  If you attempt to do so, Parse-O-Matic will terminate with
  7399.     an error.
  7400.     
  7401.     You can not delete a device (e.g. ERASE "LPT1:").  The ERASE command
  7402.     simply ignores such requests.
  7403.     
  7404.     If value1 is preceded by a "+" character, the plus sign is ignored.
  7405.     See "How Parse-O-Matic Opens an Output File" for an explanation of the
  7406.     significance of the plus sign.
  7407.     
  7408.  
  7409.  
  7410.  
  7411.  
  7412.  
  7413.  
  7414.  
  7415.  
  7416.  
  7417.  
  7418.  
  7419.  
  7420.  
  7421.  
  7422.  
  7423.  
  7424.  
  7425.  
  7426.  
  7427.  
  7428.                                                                             126
  7429.                                --------------------
  7430.                                The FILESIZE Command
  7431.                                --------------------
  7432.     
  7433.     FORMAT:        FILESIZE var1 value1
  7434.     
  7435.     PURPOSE:       Determines the size of a file, in bytes
  7436.     
  7437.     PARAMETERS:    var1   is the variable being set with the file size
  7438.                    value1 is the name of the file
  7439.     
  7440.     SEE ALSO:      "Long File Names in Win95"
  7441.     
  7442.     The FILESIZE command can be used to obtain the size of a file, or to see
  7443.     if a file exists.
  7444.     
  7445.     If the file does not exist, FILESIZE sets var1 to a null ("") string.
  7446.     
  7447.     If the file exists, FILESIZE sets var1 to the number of bytes in the
  7448.     file (from 0 to 2,147,483,647 bytes).
  7449.     
  7450.     For those rare files that are larger than 2,147,483,647 bytes, FILESIZE will
  7451.     produce an unpredictable result and may even cause Parse-O-Matic to fail.
  7452.     Nevertheless, it is possible to process such large files -- all of the other
  7453.     commands will work normally.
  7454.     
  7455.                                  ------------------
  7456.                                  The GETENV Command
  7457.                                  ------------------
  7458.     
  7459.     FORMAT:        GETENV var1 value1
  7460.     
  7461.     PURPOSE:       GETENV obtains a system environment variable
  7462.     
  7463.     PARAMETERS:    var1   is the variable being set
  7464.                    value1 is the name of the system environment variable
  7465.     
  7466.     NOTES:         System environment variables are sometimes referred to as
  7467.                    "DOS Environment Variables" or "SET Variables".
  7468.     
  7469.     SEE ALSO:      Explanations of the SET & PATH commands in your DOS manual,
  7470.                    or "The Environment Area" in your Windows or OS/2 manual.
  7471.     
  7472.     ALTERNATIVES:  See "Command-line Parameters" in the "Command-Line
  7473.                    Techniques" section of this manual.
  7474.     
  7475.     GETENV enables you to access certain important settings that concern your
  7476.     computer's operating system.  To see what settings are available, enter the
  7477.     following command at the DOS prompt:
  7478.     
  7479.     SET
  7480.     
  7481.  
  7482.  
  7483.                                                                             127
  7484.     This will display the contents of your computer's "environment area".  Two
  7485.     of the most important values in the environment area are COMSPEC and PATH.
  7486.     These are briefly described later, but refer to your operating system
  7487.     manual for full details.
  7488.     
  7489.     GETENV removes all spaces, tabs and equals-signs ("=") from value1,
  7490.     converts it to uppercase, then looks it up in the system environment area.
  7491.     
  7492.     - If it finds it, var1 is set to the corresponding value.
  7493.     - If it does not find it, var1 is set to an empty (null) string.
  7494.     
  7495.     ----------------------------------
  7496.     Disappearing Environment Variables
  7497.     ----------------------------------
  7498.     
  7499.     Sometimes an environment variable disappears for no apparent reason.  There
  7500.     are two likely reasons for this:
  7501.     
  7502.     1)  You ran out of environment space.
  7503.     
  7504.         There is only a limited amount of room in the system environment area
  7505.         (which is located in RAM memory).  If you think this is the problem,
  7506.         type your DOS SET command to save a variable into the system
  7507.         environment, then type SET by itself to review the contents of the
  7508.         environment.  If your variable does not appear, consult your operating
  7509.         system manual to find out how to expand your environment space.
  7510.     
  7511.     2)  It was set by a COPY of the operating system.
  7512.     
  7513.         If you are in Windows and you run DOS, then use the DOS SET command, it
  7514.         will only affect the environment area associated with the copy of DOS
  7515.         that you are running.  When you exit this copy and start up another
  7516.         one, it will not contain the variable.  You can address this problem by
  7517.         setting the variable in your AUTOEXEC.BAT file, or by running a batch
  7518.         file that sets the variable before running Parse-O-Matic.
  7519.     
  7520.     --------
  7521.     Examples
  7522.     --------
  7523.     
  7524.     The following command will determine which directories get searched when
  7525.     you are looking for a program or a file:
  7526.     
  7527.     GETENV path "PATH"
  7528.     
  7529.     To find out the name of your command interpreter (usually COMMAND.COM)
  7530.     and where it is located, try this command:
  7531.     
  7532.     GETENV comspec "COMSPEC"
  7533.     
  7534.     You can use GETENV as a simple "input routine" for Parse-O-Matic
  7535.     applications.  For details, see "Controlling a POM File from the Command
  7536.     Line", in the section entitled "Effective Use of Batch Files".
  7537.  
  7538.                                                                             128
  7539.                                   ---------------
  7540.                                   The LOG Command
  7541.                                   ---------------
  7542.     
  7543.     FORMAT:        LOG value1 [comparator] value2 value3 [value4 [value5]]
  7544.     
  7545.     PURPOSE:       LOG places a message (value3) in the processing log file
  7546.                    (POMLOG.TXT) if the comparison is true.  Both value4 and
  7547.                    value5 are optional; if they are present, they are added
  7548.                    to end of value3.
  7549.     
  7550.     NOTES:         The processing log is described in the section "Logging".
  7551.     
  7552.     ALTERNATIVES:  The SHOWNOTE command
  7553.     
  7554.     Here is an example of the LOG command:
  7555.     
  7556.     SET   emplnumb = $FLINE[ 1  9]
  7557.     SET   sales    = $FLINE[10 20]
  7558.     TRIM  sales "B" " "
  7559.     LOG   sales = "0" "WARNING!  Zero sales for employee number:"
  7560.     LOG   sales = "0" emplnumb
  7561.     
  7562.     This adds two warning lines to the processing log if the sales figures is
  7563.     zero.
  7564.     
  7565.     The logging feature lets you run Parse-O-Matic unattended, then come back
  7566.     later to review (via the processing log) any exceptional conditions.  For
  7567.     some additional comments on logging, see "Unattended Operation".
  7568.     
  7569.     The maximum length of a LOG string (value3, plus value4 and value5 if
  7570.     present) is 245 characters.
  7571.     
  7572.  
  7573.  
  7574.  
  7575.  
  7576.  
  7577.  
  7578.  
  7579.  
  7580.  
  7581.  
  7582.  
  7583.  
  7584.  
  7585.  
  7586.  
  7587.  
  7588.  
  7589.  
  7590.  
  7591.  
  7592.  
  7593.                                                                             129
  7594.                                 -------------------
  7595.                                 The MSGWAIT Command
  7596.                                 -------------------
  7597.     
  7598.     FORMAT:        MSGWAIT value1
  7599.     
  7600.     PURPOSE:       MSGWAIT controls the amount of time that a processing error
  7601.                    message appears on the screen before it times out. (Messages
  7602.                    from the HALT command are treated as error messages.)
  7603.     
  7604.     PARAMETERS:    value1 is the delay time in seconds
  7605.     
  7606.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  7607.     
  7608.     DEFAULTS:      If the MSGWAIT command is not included in the POM file, and
  7609.                    an error occurs, Parse-O-Matic will wait until you press a
  7610.                    key; the message will not time out.
  7611.     
  7612.     NOTES:         If value1 is "0", error messages will not time out.
  7613.                    The maximum value for value1 is 60000 (about 16 hours).
  7614.                    You can set value1 to "1", but one second is usually too
  7615.                    short a delay; a value of "60" (one minute) is better.
  7616.     
  7617.     SEE ALSO:      "The Halt Command", "Unattended Operation", "Quiet Mode"
  7618.     
  7619.     The MSGWAIT command lets you control the behavior of error messages that
  7620.     appear during the processing of an input file.  This is helpful if you
  7621.     have created POM applications that are run unattended.
  7622.     
  7623.     If Parse-O-Matic was invoked by a batch file or application program, you
  7624.     want may error messages to "time out", allowing Parse-O-Matic to terminate,
  7625.     and processing to continue.
  7626.     
  7627.     -----------------
  7628.     Standard Behavior
  7629.     -----------------
  7630.     
  7631.     If Parse-O-Matic encounters an error while reading in a POM file (i.e.
  7632.     during the "compile" step), it displays a message on the screen and waits
  7633.     until you press a key.  Parse-O-Matic then terminates.
  7634.     
  7635.     When running the actual POM file (i.e. while processing the input file),
  7636.     Parse-O-Matic will normally behave the same way:  if an error occurs (or
  7637.     if a HALT command is encountered), it will display a message on the screen
  7638.     and wait for you to press a key before it terminates.
  7639.     
  7640.  
  7641.  
  7642.  
  7643.  
  7644.  
  7645.  
  7646.  
  7647.  
  7648.                                                                             130
  7649.     ------------------------
  7650.     Setting a Time-Out Delay
  7651.     ------------------------
  7652.     
  7653.     You can use the MSGWAIT command to tell Parse-O-Matic to continue ("time
  7654.     out") after a certain number of seconds.  For example:
  7655.     
  7656.     MSGWAIT "60"
  7657.     
  7658.     This tells Parse-O-Matic to wait about 60 seconds if an error is
  7659.     encountered while processing the input file.  Parse-O-Matic will then
  7660.     terminate.  (The actual delay depends on the type of computer you are
  7661.     using; a delay of "60" will typically last between 55 and 65 seconds).
  7662.     
  7663.     ----------
  7664.     Color Cues
  7665.     ----------
  7666.     
  7667.     If you have a color monitor, you can tell if a message will "time out"
  7668.     by the color of the "Press a key to continue" prompt:
  7669.     
  7670.     - If it is magenta (sometimes called "purple") it will NOT time out
  7671.     - If it is blue, if WILL time out
  7672.     
  7673.     ------------
  7674.     Key Stacking
  7675.     ------------
  7676.     
  7677.     To ensure that an error message is not inadvertently bypassed, "stacked"
  7678.     keystrokes are ignored by Parse-O-Matic.  That is to say, if you press
  7679.     several keys before an error message is displayed, Parse-O-Matic gets rid
  7680.     of them before displaying the message.
  7681.     
  7682.     ----------
  7683.     Exceptions
  7684.     ----------
  7685.     
  7686.     If Parse-O-Matic is processing an empty input file, it will display the
  7687.     warning "Input file is empty", then continue processing the POM file when
  7688.     you press a key, or after a delay of about 60 seconds.
  7689.     
  7690.     The MSGWAIT command does not affect messages that report errors detected
  7691.     during the compilation (initial read-in) of the POM file.
  7692.     
  7693.     The MSGWAIT command does not affect the "Retry or Cancel" message that
  7694.     appears if you are dealing with a device (see "Sending Output to a
  7695.     Device").
  7696.     
  7697.  
  7698.  
  7699.  
  7700.  
  7701.  
  7702.  
  7703.                                                                             131
  7704.     -----------------
  7705.     A Word of Caution
  7706.     -----------------
  7707.     
  7708.     A POM file should be thoroughly tested before setting the MSGWAIT time to a
  7709.     value other than "0".  Most error messages are serious enough to justify
  7710.     waiting until the user acknowledges them.
  7711.     
  7712.     If you call Parse-O-Matic from a batch file or application program, you can
  7713.     check the success of the parsing job by checking the return code.  (See
  7714.     "Effective Use of Batch Files" and "Running Parse-O-Matic from Another
  7715.     Program").
  7716.     
  7717.     If there was a processing error and you did not check the parsing job
  7718.     (either by testing the program return code, or by consulting the
  7719.     processing log), the resulting oversight could be serious.
  7720.     
  7721.                                  -----------------
  7722.                                  The PAUSE Command
  7723.                                  -----------------
  7724.     
  7725.     FORMAT:        PAUSE value1
  7726.     
  7727.     PURPOSE:       Delays the specified number of milliseconds
  7728.     
  7729.     PARAMETERS:    value1 is the delay time (between 1 and 65500)
  7730.     
  7731.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  7732.     
  7733.     NOTES:         1     millisecond  = One thousandth of a second
  7734.                    100   milliseconds = One tenth of a second
  7735.                    1000  milliseconds = One second
  7736.                    60000 milliseconds = One minute
  7737.     
  7738.     Here are some typical applications of the PAUSE command:
  7739.     
  7740.     - Slow down Parse-O-Matic so you can watch the processing screen
  7741.     - Give a slow laser printer extra time to eject a page after an OUTPAGE
  7742.     - Give you time to remove a page from a dot-matrix printer after an OUTPAGE
  7743.     - Give a communications device time to complete its current operation
  7744.     
  7745.     Here is an example of the latter application:
  7746.     
  7747.     OFILE  "COM1:"             <-- Direct output to the modem on COM1
  7748.     OUTEND |ATZ                <-- Send a modem initialization command
  7749.     PAUSE  "1000"              <-- Wait one second for the command to complete
  7750.     OUTEND |ATDT555-1234       <-- Send a dialing command to the modem
  7751.     
  7752.     If your PAUSE command is 200 milliseconds or longer, Parse-O-Matic displays
  7753.     a "PAUSED" message in the lower right corner of the processing screen.
  7754.     While this appears, you can press any key to end the pause.  (We recommend
  7755.     that you use the spacebar -- and avoid the Esc key.  Parse-O-Matic
  7756.     processing will be terminated if the PAUSE happens to end at the precise
  7757.  
  7758.                                                                             132
  7759.     moment your finger is coming down on the Esc key!)
  7760.     
  7761.                                  ------------------
  7762.                                  The RANDOM Command
  7763.                                  ------------------
  7764.     
  7765.     FORMAT:        RANDOM var1 value1 value2
  7766.     
  7767.     PURPOSE:       Generates a random integer number
  7768.     
  7769.     PARAMETERS:    var1   is the variable being set
  7770.                    value1 is the minimum number allowed (between 0 and 65534)
  7771.                    value2 is the maximum number allowed (between 0 and 65534)
  7772.     
  7773.     NUMERICS:      Tabs, spaces and commas are stripped from value1
  7774.     
  7775.     The RANDOM command generates a random number in the range specified by
  7776.     value1 and value2.  For example, to simulate the rolling of a six-sided
  7777.     die:
  7778.     
  7779.     RANDOM   roll "1" "6"
  7780.     
  7781.     The first time you call this, it might set the roll variable to "3".  The
  7782.     next time, it might set it to "1".  The roll variable will never be lower
  7783.     than "1" or higher than "6".
  7784.     
  7785.     The minimum value must always be less than or equal to the maximum value.
  7786.     Thus, the following statement will cause an error:
  7787.     
  7788.     RANDOM   x "100" "1"        <-- This is incorrect
  7789.     
  7790.     If value1 and value2 are the same, RANDOM will always generate the same
  7791.     number.
  7792.     
  7793.     SET      n = "50"
  7794.     RANDOM   z n n
  7795.     
  7796.     This will always set the z variable to 50.
  7797.     
  7798.  
  7799.  
  7800.  
  7801.  
  7802.  
  7803.  
  7804.  
  7805.  
  7806.  
  7807.  
  7808.  
  7809.  
  7810.  
  7811.  
  7812.  
  7813.                                                                             133
  7814.                                 --------------------
  7815.                                 The SHOWNOTE Command
  7816.                                 --------------------
  7817.     
  7818.     FORMAT:        SHOWNOTE value1 [value2] [value3] [value4] [value5]
  7819.     
  7820.     PURPOSE:       Displays a message on the processing screen
  7821.     
  7822.     PARAMETERS:    value1 to value5 are values that will be displayed
  7823.     
  7824.     ALTERNATIVES:  The LOG command
  7825.     
  7826.     When you are doing especially intense parsing, it is nice to see some kind
  7827.     of indication of what is happening.  The SHOWNOTE command displays a message
  7828.     up to 40 characters long in the lower left corner of the processing screen.
  7829.     For example:
  7830.     
  7831.     SHOWNOTE "Reading employee data"
  7832.     
  7833.     This will display the message "Reading employee data" until the parsing job
  7834.     ends, or until another SHOWNOTE command is encountered.
  7835.     
  7836.     You can remove a note from the processing screen by providing a null value:
  7837.     
  7838.     SHOWNOTE ""
  7839.     
  7840.     This clears a note that is already on the processing screen.
  7841.     
  7842.     You can display up to 5 values in a SHOWNOTE message.  Each value will be
  7843.     separated from the others by a space.  For example:
  7844.     
  7845.     SHOWNOTE "Employee:" empnum " -- Last name:" lastname
  7846.     
  7847.     This would display a note like this:
  7848.     
  7849.     Employee: 314159 -- Last name: Smith
  7850.     
  7851.     Bear in mind that you have only 40 characters for the note.  If the lastname
  7852.     variable in the preceding example was "Von Neumann", the display would be
  7853.     truncated to forty characters, and display the note as follows:
  7854.     
  7855.     Employee: 314159 -- Last name: Von Neuma
  7856.     
  7857.  
  7858.  
  7859.  
  7860.  
  7861.  
  7862.  
  7863.  
  7864.  
  7865.  
  7866.  
  7867.  
  7868.                                                                             134
  7869.     -----------
  7870.     Other Notes
  7871.     -----------
  7872.     
  7873.     There are three kinds of notes that are displayed in the lower right corner
  7874.     of the processing screen:
  7875.     
  7876.       TYPE OF NOTE     COLOR       TEXT                   REASON
  7877.       -------------   ----------   --------------------   --------------------
  7878.       SHOWNOTE        Light Grey   Whatever you specify   The SHOWNOTE command
  7879.       PAUSE           Light Red    PAUSED                 The PAUSE command
  7880.       Error message   Red          TRYING TO PRINT        Printer is offline
  7881.     
  7882.     In most cases, these messages will not interfere with each other.
  7883.     
  7884.     ------------
  7885.     Slowing Down
  7886.     ------------
  7887.     
  7888.     If you are running Parse-O-Matic on a fast machine, your SHOWNOTE messages
  7889.     blaze by so fast that there are not particularly helpful. Here is a POM file
  7890.     that demonstrates one solution:
  7891.     
  7892.     SET      line_counter = line_counter+
  7893.     SET      note_control = note_control+
  7894.     BEGIN    note_control = "100"
  7895.       SET      note_control = "0"
  7896.       SHOWNOTE "Processing line #" line_counter
  7897.     END
  7898.     OUTEND   |{$FLINE}
  7899.     
  7900.     This will perform the SHOWNOTE command on every hundredth input line.
  7901.     
  7902.  
  7903.  
  7904.  
  7905.  
  7906.  
  7907.  
  7908.  
  7909.  
  7910.  
  7911.  
  7912.  
  7913.  
  7914.  
  7915.  
  7916.  
  7917.  
  7918.  
  7919.  
  7920.  
  7921.  
  7922.  
  7923.                                                                             135
  7924.                                  -----------------
  7925.                                  The SOUND Command
  7926.                                  -----------------
  7927.     
  7928.     FORMAT:        SOUND value
  7929.     
  7930.     PURPOSE:       The SOUND command performs two functions:
  7931.                    1)  It makes a noise, or ...
  7932.                    2)  It sets the noise made when an error occurs
  7933.     
  7934.     The SOUND command has a repertoire of nine distinctive noises:
  7935.     
  7936.     BEEP BIP BUZZ EDGE ERROR HUH PIP TRILL WHOOP
  7937.     
  7938.     These sounds are useful for alerting you to unusual situations.  Let's say
  7939.     you wanted to be warned if one of the fields in a file comes up blank.  You
  7940.     could write the code this way:
  7941.     
  7942.     BEGIN lastname = ""
  7943.       SOUND "WHOOP"
  7944.       SET   lastname = "?"
  7945.     END
  7946.     
  7947.     Case is not important; the following commands are all equivalent:
  7948.     
  7949.     SOUND "WHOOP"
  7950.     SOUND "Whoop"
  7951.     SOUND "whoop"
  7952.     
  7953.     ------------------
  7954.     The LISTEN Utility
  7955.     ------------------
  7956.     
  7957.     You can listen to any given sound by using the LISTEN command at the DOS
  7958.     prompt.  To hear what TRILL sounds like, enter this command:
  7959.     
  7960.     LISTEN trill
  7961.     
  7962.     By default, Parse-O-Matic error messages will alert you by playing the
  7963.     ERROR sound.  To hear this sound, enter the following command at the DOS
  7964.     prompt:
  7965.     
  7966.     LISTEN error
  7967.     
  7968.  
  7969.  
  7970.  
  7971.  
  7972.  
  7973.  
  7974.  
  7975.  
  7976.  
  7977.  
  7978.                                                                             136
  7979.     --------------------------------
  7980.     Changing the Error Message Sound
  7981.     --------------------------------
  7982.     
  7983.     If you find the error message sound noise annoying, you can replace it with
  7984.     one of the other sounds by using the special ERRMSG specification of the
  7985.     SOUND command.  For example, to replace the ERROR sound with the BUZZ
  7986.     sound, place this line at the top of your POM file:
  7987.     
  7988.     SOUND "ERRMSG BUZZ"
  7989.     
  7990.     If you don't want any sound made when an error occurs, use this command:
  7991.     
  7992.     SOUND "ERRMSG QUIET"
  7993.     
  7994.     The ERRMSG specification will only affect errors generated during the
  7995.     actual running of the POM file.  If an error is encountered while
  7996.     Parse-O-Matic is compiling the POM file, it will use the ERROR sound
  7997.     when it reports the problem.
  7998.     
  7999.                                  -----------------
  8000.                                  The TRACE Command
  8001.                                  -----------------
  8002.     
  8003.     FORMAT:        TRACE var1
  8004.     
  8005.     PURPOSE:       The TRACE command is an alternative to standard tracing (see
  8006.                    "Tracing", in the "Programming Techniques" section).
  8007.     
  8008.     PARAMETERS:    var1 is the variable being traced.
  8009.     
  8010.     When you include a TRACE command in your POM file, Parse-O-Matic will
  8011.     create a text file, named POM.TRC, and use it to keep a detailed record of
  8012.     POM's processing.  Here is an example of the TRACE command:
  8013.     
  8014.     TRACE PRICE
  8015.     
  8016.     This traces the variable named "PRICE".  After processing, the file POM.TRC
  8017.     will show everything that happened, and give the value of PRICE at the
  8018.     TRACE line.
  8019.     
  8020.     NOTE:  Since trace files are so detailed, they can be very large.  If you
  8021.     are trying to debug a POM file using TRACE, it is a good idea to use a
  8022.     small input file.
  8023.     
  8024.     
  8025.     
  8026.  
  8027.  
  8028.  
  8029.  
  8030.  
  8031.  
  8032.  
  8033.                                                                             137
  8034.     ============================================================================
  8035.                                        TERMS
  8036.     ============================================================================
  8037.     
  8038.                                        ------
  8039.                                        Values
  8040.                                        ------
  8041.     
  8042.     A value can be specified in the following ways:
  8043.     
  8044.     FORMAT OR SAMPLE   DESCRIPTION
  8045.     ------------------ -----------
  8046.     "text"             A literal text string
  8047.     #number            An ASCII character, in decimal (e.g. #32 = Space)
  8048.     #number#number...  Several ASCII characters (e.g. #32#32 = 2 Spaces)
  8049.     $xx                A byte, in hexadecimal (e.g. $2F = decimal 47)
  8050.     $xx$xx...          Several hex bytes ($ff$ff = binary 1111111111111111)
  8051.     VARNAME            The name of a variable
  8052.     VARNAME[start end] A substring of a variable
  8053.     VARNAME[start]     A single character
  8054.     VARNAME+           Inline incremented variable (explained below)
  8055.     VARNAME-           Inline decremented variable (explained below)
  8056.     (x,@y,z)           Deduced variable name (see "Deduced Variables")
  8057.     x,y                Explictly specified deduced variable
  8058.     
  8059.                                      ---------
  8060.                                      Variables
  8061.                                      ---------
  8062.     
  8063.     A variable is a named spot in your computer's memory that holds some data.
  8064.     
  8065.     Variable names can be up to 12 characters long.  There is no distinction
  8066.     between upper and lower case in the variable name.  A POM file can contain
  8067.     about 2000 variables and literals.
  8068.     
  8069.     In general, variable names should:
  8070.     
  8071.     - Use letters, numbers and the underscore character
  8072.     - Start with a letter
  8073.     
  8074.     It is possible to create variables that do not adhere to these rules, but
  8075.     this may cause you problems later on (particularly in subsequent releases of
  8076.     Parse-O-Matic which may use special characters to denote particular kinds of
  8077.     variables, or operations performed thereon).
  8078.     
  8079.     The # character is used to specify a literal text string of one or more
  8080.     characters.  Follow each # with the decimal value of the ASCII character
  8081.     you want.  Here are some useful values:
  8082.     
  8083.            #10 = Line Feed   #12 = Form Feed   #13 = Carriage Return
  8084.     
  8085.  
  8086.  
  8087.  
  8088.                                                                             138
  8089.                                  -----------------
  8090.                                  Predefined Values
  8091.                                  -----------------
  8092.     
  8093.     Parse-O-Matic predefines several variables.  These are:
  8094.     
  8095.     VARIABLE     DESCRIPTION
  8096.     ------------ ------------------------------------------------------------
  8097.     $FLINE       The line just read from the file (max. length 255 chars) (*)
  8098.     $FLUPC       The line just read from the file, in uppercase           (*)
  8099.     $SPLIT       The CHOP or SPLIT number you are currently processing    (*)
  8100.     $LINECOUNTER The page line to which output will go next               (*)
  8101.     $COMMAND     The current POM command line (see "POM and Wildcards")
  8102.     $BRL         The { character (used in OUT and OUTEND)
  8103.     $BRR         The } character (used in OUT and OUTEND)
  8104.     $TAB         The tab character (Hex $09; ASCII 09)
  8105.     
  8106.     (*) This is discussed in more detail, below.
  8107.     
  8108.     Although these predefined variables start with a dollar sign ($), it does
  8109.     not mean they are in some way "hexadecimal" (as in the case of the hex
  8110.     values mentioned earlier).  In this case, the $ character indicates that the
  8111.     variables are defined by Parse-O-Matic.  In general, you should avoid
  8112.     creating variables that start with anything but a letter.
  8113.     
  8114.     ------
  8115.     $FLINE
  8116.     ------
  8117.     
  8118.     CONTAINS:    The line just read from the input file
  8119.     SEE ALSO:    The READNEXT, GET and GETTEXT commands
  8120.     
  8121.     $FLINE contains the data just read from the input file (exception:  see
  8122.     "DBF Files").  The data can be intelligible (human-readable) text, or it
  8123.     can be binary information -- Parse-O-Matic does not care what $FLINE
  8124.     contains.
  8125.     
  8126.     The maximum length of $FLINE is 255 bytes.  You can use the SETLEN command
  8127.     to determine its actual length.
  8128.     
  8129.     ------
  8130.     $FLUPC
  8131.     ------
  8132.     
  8133.     CONTAINS:    The line just read from the input file, in uppercase
  8134.     SEE ALSO:    The PROPER and CVTCASE commands
  8135.     
  8136.     $FLUPC is the same as the $FLINE variable, but in uppercase.  Any changes to
  8137.     $FLINE will affect $FLUPC, since they are simply different "views" of the
  8138.     same data.
  8139.     
  8140.     $FLUPC is useful for checking for text inside the current input line if case
  8141.     is not important, and for obtaining the uppercase version of the data. For
  8142.  
  8143.                                                                             139
  8144.     example:
  8145.     
  8146.     BEGIN $FLUPC ^ "PART#"            <-- Detect "Part#", "part#" or "PART#"
  8147.       SET  partnum  = $FLUPC[10 15]   <-- Extract the part number, in uppercase
  8148.       SET  partname = $FLINE[16 30]   <-- Extract the part name, as-is
  8149.     END
  8150.     
  8151.     Since $FLUPC is really just a different view of $FLINE, a modification of
  8152.     $FLUPC (for example, using the PEEL command) is transient and usually
  8153.     pointless; the next reference to $FLUPC will simply return the uppercase
  8154.     version of $FLINE.
  8155.     
  8156.     ------
  8157.     $SPLIT
  8158.     ------
  8159.     
  8160.     CONTAINS:    The CHOP or SPLIT number you are currently processing
  8161.     SEE ALSO:    The GET and GETTEXT commands
  8162.     
  8163.     Since $FLINE has a maximum length of 255 characters, you will have to use
  8164.     the SPLIT or CHOP command if your input file is wider than that.
  8165.     
  8166.     NOTE:  Use SPLIT for text files
  8167.            Use CHOP for fixed-record-length files
  8168.     
  8169.     The $SPLIT variable reports which segment of a CHOPped or SPLIT input line
  8170.     you are currently processing.  For example, if you use this command...
  8171.     
  8172.     CHOP 1 255, 256 380
  8173.     
  8174.     then $SPLIT will be set to "1" when Parse-O-Matic processes columns 1 to
  8175.     255, and it will be set to "2" when processing columns 256 to 380.
  8176.     
  8177.     ------------
  8178.     $LINECOUNTER
  8179.     ------------
  8180.     
  8181.     CONTAINS:    The page line to which output will go next
  8182.     SEE ALSO:    "How Parse-O-Matic Opens an Output File"
  8183.     
  8184.     The $LINECOUNTER variable lets you know the number of the next output line.
  8185.     Consider this POM file:
  8186.     
  8187.     OUTEND |LINE# {$LINECOUNTER}
  8188.     OUTEND |LINE# {$LINECOUNTER}
  8189.     OUTEND |LINE# {$LINECOUNTER}
  8190.     DONE
  8191.     
  8192.     This will produce the following output:
  8193.     
  8194.     LINE# 1
  8195.     LINE# 2
  8196.     LINE# 3
  8197.  
  8198.                                                                             140
  8199.     The OUTPAGE command will reset the $LINECOUNTER to "1", since the next
  8200.     output line will be at the top of the page.  OUTHDG commands also affect
  8201.     the $LINECOUNTER variable.
  8202.     
  8203.     The $LINECOUNTER variable is active even if you have not used the PAGELEN
  8204.     command to set the page length.  By default, the page length is "0" (meaning
  8205.     "infinite"), which means that $LINECOUNTER will always be one greater than
  8206.     the total number of output lines.  However, if you specify an explicit page
  8207.     length (e.g. PAGELEN "55"), $LINECOUNTER is reset to "1" after each page
  8208.     eject.
  8209.     
  8210.     Using the SET command on $LINECOUNTER has no effect.  In some special cases,
  8211.     however, you may wish to reset $LINECOUNTER to "1".  You can do this -- even
  8212.     though you are not at the top of the page -- with the PAGELEN "0" command.
  8213.     (You can then follow this with another PAGELEN command if you want to
  8214.     restore the actual page length.)
  8215.     
  8216.     Here is a sample POM file that demonstrates why you might want to reset the
  8217.     $LINECOUNTER variable.  It will format a text file which contains a form
  8218.     feed character (ASCII 12) at the end of each page, while placing page numbers
  8219.     at the bottom of each page as a "running footing":
  8220.     
  8221.     PROLOGUE                        <-- Start of prologue
  8222.       MINLEN "0"                    <-- Allow null lines
  8223.       SET pagenum = "1"             <-- Set first page number
  8224.     END                             <-- End of prologue
  8225.     BEGIN $FLINE ^ #12              <-- Does this line have a form feed?
  8226.       BEGIN $LINECOUNTER #<= "54"   <-+
  8227.         OUTEND |                      | Put blank lines to the end of the page
  8228.         AGAIN                       <-+
  8229.       APPEND x pagenum #12          <-- Set up the footer (including form feed)
  8230.       PAD x "L" " " "80"            <-- Format the footer
  8231.       OUTEND |{x}                   <-- Output the footer
  8232.       SET pagenum = pagenum+        <-- Increment the page number
  8233.       PAGELEN "0"                   <-- Reset $LINECOUNTER to "1"
  8234.     ELSE
  8235.       OUTEND |    {$FLINE}          <-- Output a regular line
  8236.     END
  8237.     
  8238.     Note that as far as Parse-O-Matic is concerned, the "actual" output page
  8239.     length is "0" (i.e. "infinite"), but this POM file will output a text file
  8240.     that contains 55 lines per page.  (A POM file similar to the one shown is
  8241.     used, with several others, to format this manual.)
  8242.     
  8243.  
  8244.  
  8245.  
  8246.  
  8247.  
  8248.  
  8249.  
  8250.  
  8251.  
  8252.  
  8253.                                                                             141
  8254.                     -------------------------------------------
  8255.                     Running Out of Variables, Literals or Lines
  8256.                     -------------------------------------------
  8257.     
  8258.     A POM file can contain 750 lines (not counting comment lines), and about
  8259.     2000 variables and literals.  If you have a very large POM file, this may
  8260.     not be enough, and you will be forced to do the processing with two or more
  8261.     POM files.  You can link these together with a batch file, as follows:
  8262.     
  8263.     @ECHO OFF
  8264.     POM POMFILE1.POM INPUT.TXT TEMP.TXT
  8265.     IF ERRORLEVEL 1 GOTO QUIT
  8266.     POM POMFILE2.POM TEMP.TXT  FINAL.TXT
  8267.     :QUIT
  8268.     
  8269.                                      ----------
  8270.                                      Delimiters
  8271.                                      ----------
  8272.     
  8273.     If you need to specify a quotation mark, use "".  For example:
  8274.     
  8275.     IGNORE $FLINE = "He said ""Hello"" to me."
  8276.     
  8277.     This ignores any line containing:  He said "Hello" to me.
  8278.     
  8279.                                  ------------------
  8280.                                  Illegal Characters
  8281.                                  ------------------
  8282.     
  8283.     No POM command can contain these ASCII characters:
  8284.     
  8285.                          HEX    DECIMAL  NAME
  8286.                        -------  -------  --------------------
  8287.                          $00      #00    NULL
  8288.                          $0A      #10    LF (Linefeed)
  8289.                          $0D      #13    CR (Carriage Return)
  8290.     
  8291.     Of course, LF and CR do appear at the end of each line in the POM file,
  8292.     command, use either the $ or # character to denote hex or decimal literals
  8293.     (e.g. SET linefeed = $0A).
  8294.     
  8295.  
  8296.  
  8297.  
  8298.  
  8299.  
  8300.  
  8301.  
  8302.  
  8303.  
  8304.  
  8305.  
  8306.  
  8307.  
  8308.                                                                             142
  8309.                                  -----------------
  8310.                                  Using Comparators
  8311.                                  -----------------
  8312.     
  8313.     Several POM command decide what to do by comparing two values. For example:
  8314.     
  8315.     IF $FLINE[1 3] = "XYZ" THEN x = "3" ELSE "4"
  8316.     
  8317.     In this example, if the first three characters of $FLINE are "XYZ", the
  8318.     variable x is set to "3", otherwise it is set to "4".  The first equals
  8319.     sign ("=") is a "comparator", because it defines how two values will be
  8320.     compared.  The second equals sign is not a comparator; it is simply
  8321.     padding, which makes the line easier to understand (see the section
  8322.     "Padding for Clarity" for details).
  8323.     
  8324.     Parse-O-Matic supports the following comparators:
  8325.     
  8326.            COMPARATOR   INTERPRETATION   MEANING                COMMENTS
  8327.            ----------   --------------   --------------------   --------
  8328.            =                Literal      Identical
  8329.            <>               Literal      Not identical
  8330.            >                Literal      Higher                 See NOTE
  8331.            >=               Literal      Higher, or identical   See NOTE
  8332.            <                Literal      Lower                  See NOTE
  8333.            <=               Literal      Lower, or identical    See NOTE
  8334.            ^                Literal      Contains
  8335.            ~                Literal      Does not contain
  8336.            LONGER           Literal      Length is longer
  8337.            SHORTER          Literal      Length is shorter
  8338.            SAMELEN          Literal      Length is the same
  8339.            #=              Numerical     Equal
  8340.            #<>             Numerical     Not equal
  8341.            #>              Numerical     Greater
  8342.            #>=             Numerical     Greater, or equal
  8343.            #<              Numerical     Less than
  8344.            #<=             Numerical     Less than, or equal
  8345.     
  8346.     NOTE:  Depends on PC-ASCII sort order.  Refer to the section "Literal
  8347.            Comparisons and Sort Order" for details.
  8348.     
  8349.     Whenever a comparator is required, but is omitted, it is assumed to be
  8350.     "literally identical".  Thus, the following lines are equivalent:
  8351.     
  8352.         IF x y z "3" "4"                   (This is very terse, but it works)
  8353.         IF x   y THEN z = "3" ELSE "4"     (The "equals" comparator is omitted)
  8354.         IF x = y THEN z = "3" ELSE "4"     (This is a lot easier to read)
  8355.     
  8356.  
  8357.  
  8358.  
  8359.  
  8360.  
  8361.  
  8362.  
  8363.                                                                             143
  8364.     With some restrictions (discussed later), literal comparators work on
  8365.     numeric and alphabetic data.  Here are some examples of literal comparisons
  8366.     that are "true":
  8367.     
  8368.                    "ABC" <>      "ABCD"      "3" <>      "4"
  8369.                    "ABC" <=      "ABCD"      "3" <=      "4"
  8370.                    "ABC" <       "ABCD"      "3" <       "4"
  8371.                    "ABC" SHORTER "ABCD"      "3" SAMELEN "4"
  8372.     
  8373.                    "ABC" >=      "ABC"       "ABC" <>      "CDE"
  8374.                    "ABC" <=      "ABC"       "ABC" <=      "CDE"
  8375.                    "ABC" =       "ABC"       "ABC" <       "CDE"
  8376.                    "ABC" ^       "ABC"       "ABC" SAMELEN "CDE"
  8377.                    "ABC" SAMELEN "ABC"       "ABC" ~       "CDE"
  8378.     
  8379.     ----------------------------------
  8380.     Literal Comparisons and Sort Order
  8381.     ----------------------------------
  8382.     
  8383.     Some of the literal comparators compare text according to "PC-ASCII sort
  8384.     order".  For plain English text, this works fine.  However, if your text
  8385.     contains diacritical (accented) characters, you should be aware that
  8386.     some comparisons will not work correctly.  For example, the "A-Umlaut"
  8387.     character appears in the PC-ASCII character set AFTER the PC-ASCII value
  8388.     for "Z".
  8389.     
  8390.     -------------------
  8391.     Numeric Comparisons
  8392.     -------------------
  8393.     
  8394.     Some confusion can arise if you use literal comparators on numbers.  For
  8395.     example, this doesn't work as you might expect at first glance:
  8396.     
  8397.     SET count = count+
  8398.     BEGIN count >= "2"
  8399.       OUTEND x = x |{count}
  8400.     END
  8401.     
  8402.     You might expect this POM file to output any number greater than or equal
  8403.     to "2", but in fact, you will get a different result, because the
  8404.     comparison is a literal (text) comparison.  In the example above, "2" to
  8405.     "9" are greater or equal to "2", but "10" (which starts with "1") is less,
  8406.     as is evident when you sort several numbers alphabetically:
  8407.     
  8408.  
  8409.  
  8410.  
  8411.  
  8412.  
  8413.  
  8414.  
  8415.  
  8416.  
  8417.  
  8418.                                                                             144
  8419.     1
  8420.     10
  8421.     11
  8422.     15
  8423.     100
  8424.     2
  8425.     20
  8426.     200
  8427.     3
  8428.     30
  8429.     
  8430.     As you can see, the values 1, 10, 11 and 15 come before "2" when sorted
  8431.     alphabetically.
  8432.     
  8433.     To compare numbers, you should use the numeric comparators.  The correct
  8434.     way to code the previous example is as follows:
  8435.     
  8436.     SET count = count+
  8437.     BEGIN Count #>= "2"           <-- Note the #>= comparator
  8438.       OUTEND x = x |{count}
  8439.     END
  8440.     
  8441.     Written in this way, numbers greater than or equal to two will be output.
  8442.     
  8443.     Here are some examples of numeric comparisons that are "true":
  8444.     
  8445.                     "345" #<>  "567"         "1.23" #<>  "9.87"
  8446.     
  8447.                     "345" #<=  "567"         "1.23" #<=  "9.87"
  8448.     
  8449.                     "567" #>   "345"         "9.87" #>   "1.23"
  8450.     
  8451.                     "3"   #<   "6.2"
  8452.     
  8453.     The last example compares an integer ("3") with a real number ("6.2"). The
  8454.     numeric comparators automatically check if one of the numbers contains a
  8455.     decimal point.  In such case, the comparison is performed in "real number"
  8456.     mode, which imposes the accuracy restrictions described in the section "The
  8457.     CalcReal Command".  This might create a problem if you are comparing a
  8458.     decimal number with a large integer, but this is not a cause for much
  8459.     worry, since most parsing jobs tend to compare similar types of numbers.
  8460.     
  8461.     -------------------------------
  8462.     Upgrading from Earlier Versions
  8463.     -------------------------------
  8464.     
  8465.     IF YOU USED PARSE-O-MATIC PRIOR TO VERSION 3.00:  Because the comparator
  8466.     defaults to "literally identical" if it is omitted, POM files created
  8467.     before version 3.00 will continue to function normally -- with two notable
  8468.     exceptions. In older versions, the IGNORE and ACCEPT commands defaulted to
  8469.     "contains". If you have POM files that were created for older versions, you
  8470.     should check your IGNORE and ACCEPT commands to ensure that they are doing
  8471.     what you want them to.
  8472.  
  8473.                                                                             145
  8474.                                ---------------------
  8475.                                Predefined Data Types
  8476.                                ---------------------
  8477.     
  8478.     For certain commands (e.g. MAKEDATA, MAKETEXT, GET and GETTEXT),
  8479.     Parse-O-Matic has internal definitions of certain data representations;
  8480.     these are known as Parse-O-Matic's "predefined data types":
  8481.     
  8482.            DATA TYPE  BYTES  MINIMUM VALUE MAXIMUM VALUE  COMMENTS
  8483.            ---------  -----  ------------- -------------  -----------
  8484.            BYTE         1                0           255
  8485.            INTEGER      2           -32768         32767
  8486.            LONGINT      4      -2147483648    2147483647
  8487.            REAL         6    -9999999999.9  9999999999.9  See NOTE #1
  8488.            SHORTINT     1             -128           127
  8489.            WORD         2                0         65535
  8490.            DATE         -                -             -  See NOTE #2
  8491.            TRIMMED      -          0 chars     255 chars  See NOTE #3
  8492.     
  8493.     NOTE #1:  The minimum and maximum values depend on the number of digits of
  8494.               precision.  See "The CalcReal Command" for details.
  8495.     
  8496.     NOTE #2:  The DATE type does not have a specific length.  In some input
  8497.               files, a date serial number might be represented by a numeric
  8498.               format such as INTEGER or LONGINT.  For more information, see
  8499.               the discussions of the MAKETEXT, MAKEDATA and GETTEXT commands.
  8500.     
  8501.     NOTE #3:  The TRIMMED type does not have a specific length.  You can use
  8502.               it with MAKETEXT and GETTEXT commands to remove the spaces, tabs
  8503.               and nulls on either side of a string.  It can also be used with
  8504.               MAKEDATA, but since this can produce a field of indeterminate
  8505.               length, it is rarely useful in such a role.
  8506.     
  8507.     Certain predefined data types can have a qualifier, which provides
  8508.     additional information.  All commands that use predefined data types will
  8509.     accept the qualifier, but only the MAKETEXT command makes use of it.
  8510.     
  8511.     DATA TYPE  QUALIFIER DESCRIPTION     EXAMPLES
  8512.     ---------  ------------------------  -------------------------------------
  8513.     REAL       Number of decimal places  "REAL 2" -> 3.14  "REAL 4" -> 3.1415
  8514.     DATE       Date format               "DATE ?y/?n/?d" -> "96/12/01"
  8515.     
  8516.  
  8517.  
  8518.  
  8519.  
  8520.  
  8521.  
  8522.  
  8523.  
  8524.  
  8525.  
  8526.  
  8527.  
  8528.                                                                             146
  8529.     -----------------------------------
  8530.     Interpreting Data Formats in a File
  8531.     -----------------------------------
  8532.     
  8533.     When inspecting a hex dump of a binary file, bear in mind that on
  8534.     PC-compatible computers, the bytes that comprise a number are often
  8535.     reversed.  For example, for the INTEGER and WORD data types, the eight most
  8536.     significant bits of numeric values are usually placed AFTER the eight least
  8537.     significant bits.  Thus, the decimal value 5099 will appear as EB 13 in the
  8538.     file, not 13 EB, despite the fact that decimal 5099 equals hex 13EB.
  8539.     
  8540.     If you are dealing with data that treats numbers differently, you can
  8541.     sometimes work around the problem by reversing the order of the bytes
  8542.     before performing the conversion.  For example, if the file contains a WORD
  8543.     data type, but has the most significant byte FIRST, you can switch things
  8544.     around, as demonstrated by this POM file:
  8545.     
  8546.     CHOP     0                      <-- Read the file manually
  8547.     GET      x "WORD"               <-- Get two bytes from the file
  8548.     APPEND   y = x[2] x[1]          <-- Flip the bytes around
  8549.     MAKETEXT z y "WORD"             <-- Convert the number
  8550.     OUTEND   |{z}                   <-- Output the result
  8551.     
  8552.     
  8553.     
  8554.  
  8555.  
  8556.  
  8557.  
  8558.  
  8559.  
  8560.  
  8561.  
  8562.  
  8563.  
  8564.  
  8565.  
  8566.  
  8567.  
  8568.  
  8569.  
  8570.  
  8571.  
  8572.  
  8573.  
  8574.  
  8575.  
  8576.  
  8577.  
  8578.  
  8579.  
  8580.  
  8581.  
  8582.  
  8583.                                                                             147
  8584.     ============================================================================
  8585.                                  DEDUCED VARIABLES
  8586.     ============================================================================
  8587.     
  8588.                                  -----------------
  8589.                                  Deduced Variables
  8590.                                  -----------------
  8591.     
  8592.     ----------
  8593.     Definition
  8594.     ----------
  8595.     
  8596.     "Deduced Variable Names" (generally referred to as "Deduced Variables")
  8597.     provide you with powerful means for organizing and processing data.  This
  8598.     particular approach to handling variable data is not available in most
  8599.     high-level languages (e.g. C, Pascal, Basic) but is extremely helpful for a
  8600.     content-oriented language such as Parse-O-Matic.
  8601.     
  8602.     A deduced variable is a variable for which the actual name is not known when
  8603.     the program is being written.  The name itself is deduced when the actual
  8604.     POM line is run.  It is almost as if you could write a line like this:
  8605.     
  8606.     SET whatever-variable-I-should-be-using-now = "3"
  8607.     
  8608.     There are several rules by which the name is deduced.  By creating similar
  8609.     circumstances later on in the program, you can deduce the same variable name
  8610.     in another spot.
  8611.     
  8612.     Deduced variables are always surrounded by parentheses.  Here are some
  8613.     sample deduced variable names:
  8614.     
  8615.     SAMPLE      PARTS*  DEDUCTIONS  EQUIVALENT VARIABLE NAME
  8616.     ----------  ------  ----------  ------------------------
  8617.     (X)           1       None      X
  8618.     (X,Y)         2       None      X,Y
  8619.     (X,Y,Z)       3       None      X,Y,Z
  8620.     (X,@Y)        2         1       X,something
  8621.     (X,@Y,@Z)     3         2       X,something,something
  8622.     (@X,YYY,@Z)   3         2       something,YYY,something
  8623.     
  8624.     (*) A deduced variable has a maximum of three parts.
  8625.     
  8626.     As you can see:
  8627.     
  8628.     - When part of the deduced variable is NOT preceded by the "@" character,
  8629.       it is taken "as-is".
  8630.     
  8631.     - When part of the deduced variable **IS** preceded by the "@" character,
  8632.       it must be looked up.
  8633.     
  8634.  
  8635.  
  8636.  
  8637.  
  8638.                                                                             148
  8639.     -------------------
  8640.     The Look-Up Process
  8641.     -------------------
  8642.     
  8643.     The look-up process is simple:  Parse-O-Matic looks up the variable following
  8644.     the "@" character and inserts it into the deduced variable name.  For example:
  8645.     
  8646.     SET     Y = "BBB"
  8647.     SET     Z = "CCC"
  8648.     SET     (AAA,@Y,@Z) = "Quick Brown Fox"
  8649.     SET     line = (AAA,BBB,CCC)
  8650.     OUTEND  |{line}
  8651.     
  8652.     ------------
  8653.     Restrictions
  8654.     ------------
  8655.     
  8656.     There are certain limitations that affect the use of deduced variables.
  8657.     
  8658.     - You can not use them in the output picture of an OUT or OUTEND command.
  8659.       For example, the following line will result in an error:
  8660.     
  8661.       OUTEND  |We have {(PRODSTOCK,@PRODNUM} {(PRODNAMES,@PRODNUM)} in stock.
  8662.     
  8663.       The correct way to do this is as follows:
  8664.     
  8665.       SET     prodstock = (PRODSTOCK,@PRODNUM)
  8666.       SET     prodname  = (PRODNAMES,@PRODNUM)
  8667.       OUTEND  |We have {prodstock} {prodname} in stock.
  8668.     
  8669.     - The length of the deduced variable name can not exceed 12 characters.
  8670.       The following lines will result in an error:
  8671.     
  8672.       SET Part2 = "YYYYYYYYYY"
  8673.       SET Part3 = "ZZZZZZZZZZ"
  8674.       SET (XX,@Part2,@Part3) = "99"
  8675.     
  8676.       This causes an error because Parse-O-Matic tries to create a variable
  8677.       named XX,YYYYYYYYYY,ZZZZZZZZZZ -- which is 24 characters long (including
  8678.       the commas).  The maximum length for a Parse-O-Matic variable (of any
  8679.       kind) is 12 characters.  The following lines WOULD work:
  8680.     
  8681.       SET Part2 = "YYYY"
  8682.       SET Part3 = "ZZZZ"
  8683.       SET (XX,@Part2,@Part3) = "99"
  8684.     
  8685.       This would set the variable XX,YYYY,ZZZZ (which is 12 characters long,
  8686.       counting the commas) to "99".
  8687.     
  8688.  
  8689.  
  8690.  
  8691.  
  8692.  
  8693.                                                                             149
  8694.     - Deduced variables can not be used for variable CALL commands.  The
  8695.       following line would not work:
  8696.     
  8697.       CALL (ROUTINE,@RTYPE)
  8698.     
  8699.       You would have to do this as follows:
  8700.     
  8701.       SET  CallTemp = (ROUTINE,@RTYPE)
  8702.       CALL CallTemp
  8703.     
  8704.     ----------------
  8705.     Usage Guidelines
  8706.     ----------------
  8707.     
  8708.     If you know the precise name of the deduced variable you are setting, you
  8709.     can specify it directly, without the parentheses.  Thus, the following
  8710.     two commands are the same:
  8711.     
  8712.       SET (CUST,NAME,1) = "Fred Jones"
  8713.       SET  CUST,NAME,1  = "Fred Jones"
  8714.     
  8715.     In other words, if a deduced variable name does not include a look-up (i.e.
  8716.     the "@" character), it is not actually being deduced.
  8717.     
  8718.     If you use substrings with deduced variables, you must specify the indexes
  8719.     immediately after the closing parenthesis.  Thus:
  8720.     
  8721.       (Data,@Y,@Z)[10 80]               <-- This is okay
  8722.       (Data,@Y,@Z)  [10 80]             <-- This is wrong
  8723.       ( Data, @Y, @Z )[ 10 80 ]         <-- This is okay
  8724.     
  8725.     The third example shows that you can use spaces within the parentheses and
  8726.     the brackets to improve readability.
  8727.     
  8728.     Variables are "persistent" (see "Uninitialized and Persistent Variables").
  8729.     This can be a problem if you are creating variables (particularly arrays)
  8730.     while processing multiple input files:  all variables created for the
  8731.     previous input file are still around.  For this reason, you may find it
  8732.     necessary to create an initializing section (in the PROLOGUE) which ensures
  8733.     that all working variables are "set to zero", so to speak.
  8734.     
  8735.  
  8736.  
  8737.  
  8738.  
  8739.  
  8740.  
  8741.  
  8742.  
  8743.  
  8744.  
  8745.  
  8746.  
  8747.  
  8748.                                                                             150
  8749.                                   ---------------
  8750.                                   Array Variables
  8751.                                   ---------------
  8752.     
  8753.                    NOTE:  For background information, please see
  8754.                           "Deduced Variables - Definition".
  8755.     
  8756.     Array variables are deduced variables that use something distinctive about
  8757.     each input item (e.g. a product number) to allow data for similar input
  8758.     items to be treated in the same way.  Here is an example of array handling:
  8759.     
  8760.     -------------------------
  8761.     Example:  Product Numbers
  8762.     -------------------------
  8763.     
  8764.     A common requirement in data processing is to assign a number to items that
  8765.     are different instances of the same thing.  For example, let's say your
  8766.     input file contained a summary of the number of items sold at your store at
  8767.     various times of the day.  You could assign a "Product Number" to each item,
  8768.     as in the following four-line input file:
  8769.     
  8770.     10:33 AM  101  Oranges    15
  8771.     11:04 AM  102  Lemons      4
  8772.     03:15 PM  104  Bananas    20
  8773.     04:41 PM  102  Lemons     25
  8774.     :         :    :          :
  8775.     :         :    :          :
  8776.     Time   Product Product    Quantity
  8777.     Sold   Code    Name       Sold
  8778.     
  8779.     You could add up the total sales for each item, as follows:
  8780.     
  8781.     SET  ProdCode = $FLINE[11 13]
  8782.     SET  Quantity = $FLINE[27 28]
  8783.     SET  (Name,@ProdCode) = $FLINE[16 22]
  8784.     CALC (Sold,@ProdCode) = (Sold,@ProdCode) "+" Quantity
  8785.     
  8786.     The first three lines obtain the product code (e.g. 101 for Oranges), the
  8787.     quantity sold, and the product name.  The fourth line adds the quantity sold
  8788.     to the appropriate product.  Thus, after all four input lines have been
  8789.     processed, you will have created six deduced variables:
  8790.     
  8791.     VARIABLE         VALUE
  8792.     ---------------  -----
  8793.     Name,101         "Oranges"
  8794.     Name,102         "Lemons "
  8795.     Name,104         "Bananas"
  8796.     Sold,101         "15"
  8797.     Sold,102         "29"         <-- "29" is the total of 2nd and 4th input lines
  8798.     Sold,104         "20"
  8799.     
  8800.     There are no variables created for product numbers that did not appear in
  8801.     the input file, so if (for example) you test the value of Sold,103 it will
  8802.  
  8803.                                                                             151
  8804.     be reported as a null (empty) value.  That is because it was never assigned
  8805.     a value.
  8806.     
  8807.     Now that you have added up the totals, you can output them in the EPILOGUE
  8808.     section of the POM file.  (The EPILOGUE is the last section of POM code run,
  8809.     after all the input lines have been read.)
  8810.     
  8811.     EPILOGUE
  8812.       SET   MaxProdCode = "104"
  8813.       SET   ProdCode = "100"
  8814.       BEGIN
  8815.         IF     (Sold,@ProdCode) <> "" THEN NumSold = (Sold,@ProdCode) ELSE "NONE"
  8816.         PAD    (Name,@ProdCode) "R" " " "7"
  8817.         SET    ProdName = (Name,@ProdCode)
  8818.         OUTEND |Product # {ProdCode} ({ProdName}):  Sold {NumSold}
  8819.         SET    ProdCode = ProdCode+
  8820.       AGAIN ProdCode #<= MaxProdCode
  8821.     END
  8822.     
  8823.     The output from the POM file will look like this:
  8824.     
  8825.     Product # 100 (       ): Sold NONE
  8826.     Product # 101 (Oranges): Sold 15
  8827.     Product # 102 (Lemons ): Sold 29
  8828.     Product # 103 (       ): Sold NONE
  8829.     Product # 104 (Bananas): Sold 20
  8830.     
  8831.     There is no data for products 100 and 103, since they did not appear in the
  8832.     input file, so they do not show any data in the output.
  8833.     
  8834.     -----------------------
  8835.     Multidimensional Arrays
  8836.     -----------------------
  8837.     
  8838.     The example given above used "two dimensional arrays", which is to say that
  8839.     each array has two parts (e.g. Sold,101 has the parts Sold and 101).  Since
  8840.     deduced variables can have up to three parts, you can create arrays of up to
  8841.     three dimensions.
  8842.     
  8843.  
  8844.  
  8845.  
  8846.  
  8847.  
  8848.  
  8849.  
  8850.  
  8851.  
  8852.  
  8853.  
  8854.  
  8855.  
  8856.  
  8857.  
  8858.                                                                             152
  8859.                                 -------------------
  8860.                                 Eponymous Variables
  8861.                                 -------------------
  8862.     
  8863.                    NOTE:  For background information, please see
  8864.                           "Deduced Variables - Definition".
  8865.     
  8866.     Sometimes you do not have a convenient number (such as a product number) to
  8867.     organize your arrays.  In such cases, you can use the input item itself as
  8868.     the name of the variable.  This technique is known as "eponymous variables".
  8869.     (Eponymous means "self-naming".)
  8870.     
  8871.     Let us say your store sells only two items -- dogs and cats -- and you do
  8872.     not have a product number for each.   Your input file may look like this:
  8873.     
  8874.     10:00  Cat    1
  8875.     10:30  Dog    2
  8876.     11:00  Cat   10
  8877.     11:30  Cat    1
  8878.     12:00  Dog    1
  8879.     
  8880.     You can add up the items with the following POM file:
  8881.     
  8882.     SET   type  = $FLINE[ 8 10]
  8883.     SET   quant = $FLINE[14 15]
  8884.     CALC  (@type) = (@type) "+" quant
  8885.     
  8886.     After all of the input lines are read, you will have created two eponymous
  8887.     variables, as follows:
  8888.     
  8889.     VARIABLE         VALUE
  8890.     ---------------  -----
  8891.     Cat              "12"     <-- Total of input lines 1, 3 and 4
  8892.     Dog              "3"      <-- Total of input lines 2 and 5
  8893.     
  8894.     The totals can then be output in the EPILOGUE, using the following POM code:
  8895.     
  8896.     EPILOGUE
  8897.       OUTEND |Cats sold:  {Cat}
  8898.       OUTEND |Dogs sold:  {Dog}
  8899.     END
  8900.     
  8901.     If you decide to add cows to your product line-up, you need only add a
  8902.     single line to your EPILOGUE:
  8903.     
  8904.       OUTEND |Cows sold:  {Cow}
  8905.     
  8906.     Eponymous techniques can be more complicated than the example shown.  For
  8907.     example, you could create sub-categories such as Dog,Beagle,Large.
  8908.     
  8909.  
  8910.  
  8911.  
  8912.  
  8913.                                                                             153
  8914.     ------------------------
  8915.     Drawbacks and Advantages
  8916.     ------------------------
  8917.     
  8918.     The main drawback of eponymous variables is that the POM file must "know"
  8919.     all the possible variable names in order to output them.  If you have a
  8920.     small number of items (e.g. Cat, Dog, Cow) this is not a serious problem.
  8921.     If you DO have a large number of items, you can build an array -- "on the
  8922.     fly" as it were -- that adds each new eponymous variable name as it is
  8923.     created. You could then loop through this array, during output, to obtain
  8924.     the names.
  8925.     
  8926.     This may sound complex, but it is enormously powerful.  It means that you
  8927.     can create a parsing application that can handle input files containing
  8928.     items whose names are unknown to you.  A properly constructed POM file would
  8929.     handle new items without any modifications to the POM code.
  8930.     
  8931.     
  8932.     
  8933.  
  8934.  
  8935.  
  8936.  
  8937.  
  8938.  
  8939.  
  8940.  
  8941.  
  8942.  
  8943.  
  8944.  
  8945.  
  8946.  
  8947.  
  8948.  
  8949.  
  8950.  
  8951.  
  8952.  
  8953.  
  8954.  
  8955.  
  8956.  
  8957.  
  8958.  
  8959.  
  8960.  
  8961.  
  8962.  
  8963.  
  8964.  
  8965.  
  8966.  
  8967.  
  8968.                                                                             154
  8969.     ============================================================================
  8970.                                   VALUE TECHNIQUES
  8971.     ============================================================================
  8972.     
  8973.                 This section describes useful techniques you can use
  8974.                      when dealing with variables and literals.
  8975.     
  8976.                        --------------------------------------
  8977.                        Uninitialized and Persistent Variables
  8978.                        --------------------------------------
  8979.     
  8980.     Even before a variable is assigned a value (using the SET command, for
  8981.     example), you can use it in a POM command.  An uninitialized variable has a
  8982.     null value ("") and is treated normally by all commands.
  8983.     
  8984.     EXCEPTION:  To help you catch coding errors, the OUT and OUTEND commands
  8985.     do not allow you to output an uninitialized variable.  If you attempt to
  8986.     do so, Parse-O-Matic issues a warning, and processing is terminated.
  8987.     
  8988.     Variables are "persistent":  once you have assigned a value to a variable,
  8989.     it retains that value until it is changed.  Even if you open a new input
  8990.     file (see "POM and Wildcards") or a new output file (see "The OFile
  8991.     Command"), all variables will retain their values; they will not be "reset"
  8992.     back to null.  (Of course, when Parse-O-Matic ends, all variables
  8993.     disappear; they are not retained between separate runs of POM.)
  8994.     
  8995.     -------
  8996.     Example
  8997.     -------
  8998.     
  8999.     Here is an example which illustrates why persistent variables are useful:
  9000.     
  9001.     PAGELEN "55"                       <-- Set page length
  9002.     SET partnum = $FLINE[ 1 10]        <-- Extract the part number
  9003.     SET descrip = $FLINE[12 60]        <-- Extract the description
  9004.     BEGIN lastpart <> partnum          <-- Is this a new part number?
  9005.       OUTPAGE                          <-- Generate a page eject
  9006.       OUTHDG |PartNumber Description   <-- Output a heading
  9007.       OUTHDG |---------- -----------   <-- Output a heading
  9008.       SET    lastpart = partnum        <-- Remember the current part number
  9009.     END                                <-- End of BEGIN block
  9010.     OUTEND |{partnum} {descrip}        <-- Output the part number
  9011.     
  9012.     The first time a line is read from the input file, the lastpart variable
  9013.     will be null ("") because it has not yet been initialized.  As a result,
  9014.     the BEGIN block will be executed.  (The OUTPAGE command will be ignored
  9015.     in this first instance, since no data has been sent to the output file.)
  9016.     The BEGIN block also sets the lastpart variable, which will retain that
  9017.     value until it is changed.
  9018.     
  9019.     When the second input line is read (and the POM code is run again from the
  9020.     top), the BEGIN block will be run only if the current part number is
  9021.     different from the previous one (which we saved in the lastpart variable).
  9022.  
  9023.                                                                             155
  9024.     However, if the partnum variable is different, the BEGIN block will be run,
  9025.     outputting the page eject and headings, and once again saving the partnum
  9026.     in the lastpart variable, so we can check it during the third input line --
  9027.     and so on.
  9028.     
  9029.                         ------------------------------------
  9030.                         Inline Incrementing and Decrementing
  9031.                         ------------------------------------
  9032.     
  9033.     You can add "1" to a variable in a command.  For example:
  9034.     
  9035.     SET x = "3"
  9036.     SET x = x+
  9037.     
  9038.     After the second statement, x would have the value "4".  Here are some
  9039.     additional examples:
  9040.     
  9041.     - Incrementing "1" gives you "2"
  9042.     - Incrementing "9" gives you "10"
  9043.     - Incrementing "99" gives you "100"
  9044.     
  9045.     The first time a variable is referenced, it has a null value (unless you
  9046.     SET it yourself).  If you increment a null variable, it will be changed
  9047.     from "" (i.e. null) to "1".
  9048.     
  9049.     You can also subtract "1" from a variable in a command:
  9050.     
  9051.     SET x = "3"
  9052.     SET x = x-
  9053.     
  9054.     After the second statement, x would have the value "2".  Here are some
  9055.     additional examples:
  9056.     
  9057.     - Decrementing "0" gives you "-1"
  9058.     - Decrementing "1" gives you "0"
  9059.     - Decrementing "99" gives you "98"
  9060.     
  9061.     When you do an inline increment or decrement, the variable itself is not
  9062.     changed.  (C programmers take note!)  For example:
  9063.     
  9064.     SET y = "3"
  9065.     SET x = y-
  9066.     
  9067.     After the second line, the x variable will equal "2", while the y variable
  9068.     will still equal "3".
  9069.     
  9070.     You can use inline incrementing or decrementing with substrings:
  9071.     
  9072.     SET y = "X23X"
  9073.     SET x = y[2 3]+
  9074.     
  9075.     After the second line, the x variable will equal "24", while the y variable
  9076.     will still equal "X23X".
  9077.  
  9078.                                                                             156
  9079.     Only integer numeric values can be incremented or decremented.  If you
  9080.     attempt to increment or decrement another type of variable (e.g. text or a
  9081.     decimal number), Parse-O-Matic will halt, and report an error.
  9082.     
  9083.                                    -------------
  9084.                                    Line Counters
  9085.                                    -------------
  9086.     
  9087.     If your input record is divided over several lines (due to its original
  9088.     format or perhaps because you used the SPLIT or CHOP command), it is
  9089.     helpful to set up a line counter.  The following example extracts the first
  9090.     six characters of the second line of input records that span three lines
  9091.     (designated lines 0, 1 & 2):
  9092.     
  9093.     IF     LineCntr = "1" THEN MyField = $FLINE[1 6]
  9094.     OUTEND LineCntr = "1" |{MyField}
  9095.     IF     LineCntr = "2" THEN LineCntr = "" ELSE LineCntr+
  9096.     
  9097.     For an alternative to line counters, see "The ReadNext Command".
  9098.     
  9099.                                 -------------------
  9100.                                 The SHOWNUM Utility
  9101.                                 -------------------
  9102.     
  9103.     The ShowNum program (SHOWNUM.EXE in the standard Parse-O-Matic package) is a
  9104.     small utility which converts a hex number to decimal and vice-versa. It can
  9105.     also convert a character to its ASCII equivalent value in decimal or hex.
  9106.     
  9107.     ShowNum is helpful when you are working on a task that forces you to deal
  9108.     with data in hex or decimal form.  It is a handy tool if you are working
  9109.     with binary input or output files.
  9110.     
  9111.     You can probably find fancier conversion-reference utilities than SHOWNUM,
  9112.     but this one comes ready-to-go with Parse-O-Matic -- and it is free.  You
  9113.     may give unaltered copies of SHOWNUM to anybody without paying royalties.
  9114.     
  9115.     ----------------------
  9116.     Quick Reference Screen
  9117.     ----------------------
  9118.     
  9119.     To display a quick-reference help screen, enter the following command at
  9120.     the DOS prompt:
  9121.     
  9122.     SHOWNUM /?
  9123.     
  9124.     If you are calling SHOWNUM from Windows, you can add the /P (Pause) option
  9125.     to make it wait for a keypress before terminating:
  9126.     
  9127.     SHOWNUM /? /P
  9128.     
  9129.  
  9130.  
  9131.  
  9132.  
  9133.                                                                             157
  9134.     -------------------
  9135.     Converting a Number
  9136.     -------------------
  9137.     
  9138.     To find out what the decimal number 123 is in hexadecimal, enter the
  9139.     following command at the DOS prompt:
  9140.     
  9141.     SHOWNUM #123
  9142.     
  9143.     The # character tells ShowNum that the number is in decimal.  The program
  9144.     will display:
  9145.     
  9146.     #123 = $7B
  9147.     
  9148.     To find out what hex 400F is in decimal, enter the following command at
  9149.     the DOS prompt:
  9150.     
  9151.     SHOWNUM $400F
  9152.     
  9153.     The $ character tells ShowNum that the number is in hexadecimal.  The
  9154.     program will display:
  9155.     
  9156.     $400F = #16399
  9157.     
  9158.     ShowNum can handle numbers between -2,147,483,648 (hex $80000000) and
  9159.     2,147,483,647 (hex $7FFFFFFF).
  9160.     
  9161.     ----------------------
  9162.     Converting a Character
  9163.     ----------------------
  9164.     
  9165.     To find out a character's ASCII equivalent value in decimal and hex, use
  9166.     the SHOWNUM utility this way:
  9167.     
  9168.     SHOWNUM A
  9169.     
  9170.     This will display:
  9171.     
  9172.     A = #65 $41
  9173.     
  9174.     In other words, the letter "A" is ASCII decimal 65, which is hex 41.
  9175.     
  9176.     You can enclose the character in quotes if you wish.  This is strictly
  9177.     necessary only if you are trying to remember the values for "space":
  9178.     
  9179.     SHOWNUM " "
  9180.     
  9181.     This will display:
  9182.     
  9183.     " " = #32 $20
  9184.     
  9185.  
  9186.  
  9187.  
  9188.                                                                             158
  9189.     Character conversion works only one character at a time:
  9190.     
  9191.     SHOWNUM "ABCD"       <-- This is incorrect
  9192.     
  9193.     This would display:
  9194.     
  9195.     "ABCD" = #65 $41
  9196.     
  9197.     As you can see, only the first character ("A") is being converted.
  9198.     
  9199.     ----------------------
  9200.     Windows Considerations
  9201.     ----------------------
  9202.     
  9203.     Depending on how you call SHOWNUM from Windows, your answer may vanish when
  9204.     the program ends.  You can use the /P option to pause the program just
  9205.     before it terminates, to give yourself time to see the result.
  9206.     
  9207.     The /P option goes after the number or character parameter, as in these
  9208.     examples:
  9209.     
  9210.     SHOWNUM #123 /P
  9211.     SHOWNUM $3F2E70AE /P
  9212.     SHOWNUM A /P
  9213.     SHOWNUM "B" /P
  9214.     
  9215.     In each case the answer will be displayed, and the program will wait until
  9216.     you hit a key before terminating.
  9217.     
  9218.     You can set up a PIF file or "shortcut" (see your Windows documentation) to
  9219.     leave the window open after the program is finished, which means you do not
  9220.     have to use the /P option.  You may wish to set the PIF file to allow
  9221.     "cutting and pasting" from the program window.  This will allow you to copy
  9222.     the answer to your Windows environment -- which is easier (and more
  9223.     reliable) than writing it down then retyping it.
  9224.     
  9225.     Alternatively, you can start up a DOS shell from Windows, use SHOWNUM as
  9226.     many times as you want, then type EXIT at the DOS prompt when you are
  9227.     finished.
  9228.     
  9229.     
  9230.     
  9231.  
  9232.  
  9233.  
  9234.  
  9235.  
  9236.  
  9237.  
  9238.  
  9239.  
  9240.  
  9241.  
  9242.  
  9243.                                                                             159
  9244.     ============================================================================
  9245.                                PROGRAMMING TECHNIQUES
  9246.     ============================================================================
  9247.     
  9248.                     This section describes techniques that will
  9249.                         help you create and debug POM files.
  9250.     
  9251.                                       -------
  9252.                                       Tracing
  9253.                                       -------
  9254.     
  9255.     By setting the DOS variable POM to ALL, you can generate a trace file,
  9256.     named POM.TRC.  This is helpful if you have trouble understanding why your
  9257.     file isn't being parsed properly.  But be sure to test it with a SMALL
  9258.     input file; the trace is quite detailed, and it can easily generate a huge
  9259.     output file.
  9260.     
  9261.     To save space, you can specify a particular list of variables to be traced,
  9262.     rather than tracing everything.  For example, to trace only the variable
  9263.     PRICE, enter this DOS command:
  9264.     
  9265.     SET POM=PRICE
  9266.     
  9267.     To trace several variables, separate the variable names by slashes, as in
  9268.     this example:
  9269.     
  9270.     SET POM=PRICE/BONUS/NAME
  9271.     
  9272.     This traces the three variables PRICE, BONUS and NAME.
  9273.     
  9274.  
  9275.  
  9276.  
  9277.  
  9278.  
  9279.  
  9280.  
  9281.  
  9282.  
  9283.  
  9284.  
  9285.  
  9286.  
  9287.  
  9288.  
  9289.  
  9290.  
  9291.  
  9292.  
  9293.  
  9294.  
  9295.  
  9296.  
  9297.  
  9298.                                                                             160
  9299.                                       -------
  9300.                                       Logging
  9301.                                       -------
  9302.     
  9303.     Every time Parse-O-Matic runs, it creates a "processing log".  This is a
  9304.     text file named POMLOG.TXT, which is placed in Parse-O-Matic's home
  9305.     directory.  (For example, if POM.EXE is located in C:\POM, the file will
  9306.     be C:\POM\POMLOG.TXT even if you run POM from another directory.)  If the
  9307.     file POMLOG.TXT already exists, it is renamed to POMLOG.BAK.
  9308.     
  9309.     The processing log file POMLOG.TXT contains a report of what happened
  9310.     during the last run of Parse-O-Matic.  Usually, the file will be quite
  9311.     short and look something like this:
  9312.     
  9313.         COMMAND: POM TEST.POM TEST.TXT TEMP.TXT
  9314.         DATE:    AUG 01 1997
  9315.     
  9316.         17:50:10 TEST.TXT opened for processing
  9317.         17:50:14 TEST.TXT processing completed
  9318.     
  9319.     The first line gives the DOS command line, while the second gives the
  9320.     date.  Subsequent lines give the time (Hours:Minutes:Seconds) and a
  9321.     progress or error message.
  9322.     
  9323.     If you encounter an error during processing, the text of the warning
  9324.     message is saved in the processing log.  It might look something like this:
  9325.     
  9326.         COMMAND: POM TEST.POM TEST.TXT TEMP.TXT
  9327.         DATE:    AUG 01 1997
  9328.     
  9329.         17:50:10 TEST.TXT opened for processing
  9330.         17:50:10 Execution error in line number 3 of POM file TEST.POM
  9331.         17:50:11 Required parameter is missing in OUT
  9332.     
  9333.     If you process multiple input files, POMLOG.TXT might look something
  9334.     like this:
  9335.     
  9336.         COMMAND: POM EXAMPL15.POM DATA*.TXT TEMP.TXT
  9337.         DATE:    AUG 01 1997
  9338.     
  9339.         14:21:27 DATA01.TXT opened for processing
  9340.         14:21:28 DATA01.TXT processing completed
  9341.     
  9342.         14:21:28 DATA02.TXT opened for processing
  9343.         14:21:28 DATA02.TXT processing completed
  9344.     
  9345.         14:21:28 DATA03.TXT opened for processing
  9346.         14:21:28 DATA03.TXT processing completed
  9347.     
  9348.     If for some reason the processing log can not be created, Parse-O-Matic
  9349.     will continue to run; it will not terminate.  For some additional comments
  9350.     on logging, see "Unattended Operation".
  9351.     
  9352.  
  9353.                                                                             161
  9354.     ============================================================================
  9355.                               COMMAND-LINE TECHNIQUES
  9356.     ============================================================================
  9357.     
  9358.                      This section describe the various options
  9359.                            available at the command line.
  9360.     
  9361.                                      ----------
  9362.                                      Quiet Mode
  9363.                                      ----------
  9364.     
  9365.     Sometimes you don't want the user to see the Parse-O-Matic processing
  9366.     screen.  In such cases, you can use the "Quiet Mode" switch (/Q) on the
  9367.     command line.  For example:
  9368.     
  9369.     POM XYZ.POM MYFILE.TXT TEMP.TXT /Q
  9370.     
  9371.     The /Q switch suppresses the display of the processing screen.  The only
  9372.     time a user will see anything is if there is a problem (for example:  the
  9373.     input file was not found).  In such case, Parse-O-Matic will make a noise
  9374.     via the PC speaker, then display a message (see "Unattended Operation" and
  9375.     "The MSGWAIT Command" for some background information).
  9376.     
  9377.                        --------------------------------------
  9378.                        User-Specified Command-Line Parameters
  9379.                        --------------------------------------
  9380.     
  9381.     Some POM applications are easier to use if you can pass a value on the
  9382.     command line.  For example, let us say you have created a POM file that will
  9383.     search a text file for a particular word, and output all the lines that
  9384.     contain that word.  You could manually change the POM file each time, but
  9385.     this is not a practical solution if many people will be using the
  9386.     application.
  9387.     
  9388.     The alternative is to use user-defined command line parameters to pass the
  9389.     value.  Consider this POM file, which we will name FINDWORD.POM:
  9390.     
  9391.     ACCEPT $FLINE ^ $CMDLINEX
  9392.     OUTEND |{$FLINE}
  9393.     
  9394.     This will output any lines that contain (^) the value of $CMDLINEX.  This
  9395.     variable is set if you use the /X command line parameter.  Thus, you would
  9396.     call the POM file as follows:
  9397.     
  9398.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /Xadministration
  9399.     
  9400.     This would read the file INPUT.TXT and send any lines containing the word
  9401.     "administration" (in lowercase) to the file OUTPUT.TXT.
  9402.     
  9403.  
  9404.  
  9405.  
  9406.  
  9407.  
  9408.                                                                             162
  9409.     There are three user-specified command line parameters:
  9410.     
  9411.     PARAMETER   SETS VARIABLE
  9412.     ---------   -------------
  9413.        /X         $CMDLINEX
  9414.        /Y         $CMDLINEY
  9415.        /Z         $CMDLINEZ
  9416.     
  9417.     Like all variables, the $CMDLINEx variables can be in uppercase, lowercase
  9418.     or mixed case (e.g. $CmdLineX).
  9419.     
  9420.     Case Considerations
  9421.     -------------------
  9422.     
  9423.     The parameter letter (e.g. /X) can be in uppercase or lowercase.  The
  9424.     following two command lines are equivalent:
  9425.     
  9426.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /Xadministration
  9427.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /xadministration
  9428.     
  9429.     The value following the parameter letter is passed on "as-is"; it is not
  9430.     converted to uppercase or changed in any way.  You could modify the FINDWORD
  9431.     file (described earlier) to ignore case, as follows:
  9432.     
  9433.     CVTCASE $CMDLINEX $CMDLINEX   <-- Convert the /X value to uppercase
  9434.     ACCEPT  $FLUPC ^ $CMDLINEX    <-- Compare to the uppercase version of $FLINE
  9435.     OUTEND  |{$FLINE}             <-- Output the line if the value was found
  9436.     
  9437.     Spaces in Values
  9438.     ----------------
  9439.     
  9440.     Since command-line parameters are separated by spaces, you must enclose your
  9441.     parameter value in quotes if it contains one or more spaces.  For example:
  9442.     
  9443.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /X"Mr. Jones"
  9444.     
  9445.     If the parameter value contains quotes, they must be doubled-up.  Thus, if
  9446.     you were using the FINDWORD application to find
  9447.     
  9448.     The "King" of American Jazz
  9449.     
  9450.     the command would look like this:
  9451.     
  9452.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /X"The ""King"" of American Jazz"
  9453.     
  9454.     Command-Line Switches
  9455.     ---------------------
  9456.     
  9457.     Sometimes you want a command-line parameter to simply mean "do something".
  9458.     If it is missing from the command line, it would mean "don't do it".  You
  9459.     could specify /ZY (for "Yes, do it") and /ZN (for "No, don't do it"), but
  9460.     there is an easier way.
  9461.     
  9462.  
  9463.                                                                             163
  9464.     If a command-line parameter is missing, Parse-O-Matic sets its corresponding
  9465.     $CMDLINEx variable to "N" (meaning, "No, it's not there").  If the parameter
  9466.     is present -- with no value following it -- Parse-O-Matic sets the $CMDLINEx
  9467.     variable to "Y" (meaning "Yes, it's there").  We can use this method to
  9468.     refine the FINDWORD application described earlier...
  9469.     
  9470.     BEGIN $CMDLINEZ = "Y"
  9471.       CVTCASE $CMDLINEX $CMDLINEX
  9472.       ACCEPT  $FLUPC ^ $CMDLINEX
  9473.     ELSE
  9474.       ACCEPT  $FLINE ^ $CMDLINEX
  9475.     END
  9476.     OUTEND  |{$FLINE}
  9477.     
  9478.     In this case, the /X value (the word we are looking for) will be tested
  9479.     without regard to case (i.e. uppercase or lowercase letters) if /Z is
  9480.     present on the command line.  If /Z is missing, we will look for an exact
  9481.     match.  Here are two sample command lines:
  9482.     
  9483.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /X"Mr. Jones"
  9484.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /X"Mr. Jones" /Z
  9485.     
  9486.     The first command would not match "Mr. Jones" with "mr. jones".  The second
  9487.     command would consider the two strings equivalent.
  9488.     
  9489.     Hex and Decimal Code Strings
  9490.     ----------------------------
  9491.     
  9492.     You can specify precise values either as a decimal ("ASCII") value, or as
  9493.     hexadecimal.  For example, the following three commands are equivalent:
  9494.     
  9495.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /X" 01"
  9496.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /X$20$30$31
  9497.     POM FINDWORD.POM INPUT.TXT OUTPUT.TXT /X#32#45#49
  9498.     
  9499.     All three specify the search string " 01".  The second one uses decimal
  9500.     notation for the characters, while the third one uses hexadecimal codes
  9501.     for the characters.
  9502.     
  9503.     You can not mix the decimal, hex and literal representations.  Here are
  9504.     two examples:
  9505.     
  9506.     /X#32"22"#32     is not permitted
  9507.     /X" 22 "         could be used instead
  9508.     /X#32#50#50#32   could also be used
  9509.     
  9510.     /X$30#50         is not permitted
  9511.     /X02             could be used instead
  9512.     /X"02"           could also be used
  9513.     
  9514.  
  9515.  
  9516.  
  9517.  
  9518.                                                                             164
  9519.                                       -------
  9520.                                       Summary
  9521.                                       -------
  9522.     
  9523.                SAMPLE COMMAND LINE                 VALUE OF $CMDLINEX
  9524.                ----------------------------------  ------------------
  9525.                POM A.POM B.TXT C.TXT /XHarry       Harry
  9526.                POM A.POM B.TXT C.TXT /X"The King"  The King
  9527.                POM A.POM B.TXT C.TXT /X            Y
  9528.                POM A.POM B.TXT C.TXT /XY           Y
  9529.                POM A.POM B.TXT C.TXT /XN           N
  9530.                POM A.POM B.TXT C.TXT               N
  9531.                POM A.POM B.TXT C.TXT /X$30$31      01
  9532.                POM A.POM B.TXT C.TXT /X#48#50      02
  9533.     
  9534.     
  9535.     
  9536.  
  9537.  
  9538.  
  9539.  
  9540.  
  9541.  
  9542.  
  9543.  
  9544.  
  9545.  
  9546.  
  9547.  
  9548.  
  9549.  
  9550.  
  9551.  
  9552.  
  9553.  
  9554.  
  9555.  
  9556.  
  9557.  
  9558.  
  9559.  
  9560.  
  9561.  
  9562.  
  9563.  
  9564.  
  9565.  
  9566.  
  9567.  
  9568.  
  9569.  
  9570.  
  9571.  
  9572.  
  9573.                                                                             165
  9574.     ============================================================================
  9575.                                    FILE HANDLING
  9576.     ============================================================================
  9577.     
  9578.                        -------------------------------------
  9579.                        How Parse-O-Matic Searches for a File
  9580.                        -------------------------------------
  9581.     
  9582.     When Parse-O-Matic needs to read a file, it follows this procedure:
  9583.     
  9584.     1)  Parse-O-Matic tidies up the file name in the following ways:
  9585.     
  9586.         - It removes spaces and tabs
  9587.         - It converts the file name to uppercase
  9588.         - As per DOS convention, slashes (/) are converted to backslashes (\)
  9589.         - If this type of file has a default extension, and if the file name
  9590.           does not have a period (i.e. dot) in the name, the extension is
  9591.           added.
  9592.     
  9593.     2)  If the file name is fully qualified (i.e. drive and path, or both),
  9594.         Parse-O-Matic tries to open that file.  If it can not, it terminates
  9595.         with an error message.
  9596.     
  9597.     3)  If the file name is not fully qualified, Parse-O-Matic follows this
  9598.         procedure:
  9599.     
  9600.         - It first looks for the file in the current directory.
  9601.         - If then looks in the directory where the Parse-O-Matic program
  9602.           (POM.EXE) is located.
  9603.         - It then searches the DOS PATH for the file.  (For information
  9604.           about the PATH command, refer to your operating system manual.)
  9605.         - If none of these steps locate the file, Parse-O-Matic terminates
  9606.           with an error message.
  9607.     
  9608.     The following types of files are affected...
  9609.     
  9610.     TYPE OF FILE            DEFAULT EXTENSION  REFER TO MANUAL SECTION
  9611.     ----------------------  -----------------  -----------------------
  9612.     POM (Control) File            .POM         "The POM File"
  9613.     POJ (Job) File                .POJ         "Parse-O-Matic Job (POJ) Files"
  9614.     Date Information File      See NOTE #1     "The POMDATE.CFG File"
  9615.     Lookup File                See NOTE #2     "The LookFile Command"
  9616.     Properization Exception    See NOTE #2     "The Proper Command"
  9617.     Map File                      .MPF         "The MAPFILE Command"
  9618.     
  9619.     NOTE #1:  The Date Information File is always called POMDATE.CFG.  You can
  9620.               put your standard version in the Parse-O-Matic directory. If you
  9621.               wish to override it, you should place the modified copy in your
  9622.               current (logged) directory.
  9623.     
  9624.     NOTE #2:  This type of file does not have a default extension.  However, we
  9625.               recommend "TBL" (i.e. "Table") for Lookup files and "PEF" for
  9626.               Properization Exception Files.
  9627.  
  9628.                                                                             166
  9629.     Parse-O-Matic does NOT search for input and output files.  They must be
  9630.     in the current directory, or must have a fully qualified path.  If the
  9631.     input file is missing an extension, it is assumed to be TXT.  If the
  9632.     output file is not specified in the POM command, it is assumed to be
  9633.     Output File")
  9634.     
  9635.     Since Parse-O-Matic searches for files, you can place frequently-used
  9636.     Lookup and POM files in a directory in your DOS path.
  9637.     
  9638.                        --------------------------------------
  9639.                        How Parse-O-Matic Opens an Output File
  9640.                        --------------------------------------
  9641.     
  9642.     Parse-O-Matic opens an output file the first time one of the output
  9643.     commands (e.g. OUT, OUTEND, OUTHDG) has something to send to the file.
  9644.     When opening an output file, Parse-O-Matic follows this procedure:
  9645.     
  9646.     1)  Normally, the name of the output file is specified on the POM command
  9647.         line or (if it is omitted there), it is specified in an OFILE command
  9648.         within the POM file.
  9649.     
  9650.         If no output file name was given using either method, the name is set
  9651.         to POMOUT.TXT (in the current directory).
  9652.     
  9653.     2)  Parse-O-Matic tidies up the file name in the following ways:
  9654.     
  9655.         - It removes spaces and tabs
  9656.         - It converts the file name to uppercase
  9657.         - As per DOS convention, slashes (/) are converted to backslashes (\)
  9658.         - If the file name does not have an extension, and it does not end in
  9659.           a period or a colon, the extension TXT is added.  Thus:
  9660.     
  9661.           C:\XYZ      becomes C:\XYZ.TXT
  9662.           C:\XYZ.     stays the same
  9663.           C:\XYZ.DAT  stays the same
  9664.           LPT2:       stays the same (see "Sending Output to a Device")
  9665.     
  9666.     3)  The output file name is compared to the input file name.  If they are
  9667.         the same, Parse-O-Matic terminates with an error.  You can not send
  9668.         output to the input file, nor can you read input from the output file.
  9669.     
  9670.     4A) If the file name is preceded by a plus sign ("+"), Parse-O-Matic will
  9671.         append output to the file.  Here are some examples:
  9672.     
  9673.         +C:\XYZ.TXT   output will be appended to the file
  9674.         +LPT1:        this refers to a device, so the "+" is ignored
  9675.     
  9676.         If the file to which you are appending does not already exist, it is
  9677.         first created, as an empty file.
  9678.     
  9679.  
  9680.  
  9681.  
  9682.  
  9683.                                                                             167
  9684.     4B) If the file name is NOT preceded by a plus sign, the following
  9685.         procedure takes place:
  9686.     
  9687.         - If a file with the specified name already exists, it is renamed
  9688.           with a .BAK extension (replacing any previous file with that name).
  9689.         - The file is created, as an empty file
  9690.     
  9691.         For example, if you run Parse-O-Matic as follows:
  9692.     
  9693.         POM MYPOM.POM INPUT.TXT C:\XYZ.TXT
  9694.     
  9695.         then if C:\XYZ.TXT already exists, it is renamed to C:\XYZ.BAK.
  9696.     
  9697.     5)  Output is directed to the output file until Parse-O-Matic ends or a new
  9698.         output file name is specified by the OFILE command.
  9699.     
  9700.     REMINDER:  Parse-O-Matic does not open the output file until it is time to
  9701.     send it some data from the output commands (OUT, OUTEND etc.).  If no data
  9702.     is sent to the output file, it will contain its original data (assuming it
  9703.     already existed).  If this is a problem, you can either delete the output
  9704.     file before running Parse-O-Matic, or place the following commands in the
  9705.     PROLOGUE:
  9706.     
  9707.     ERASE "OUTPUT.TXT"      <-- Delete the output file
  9708.     OFILE "OUTPUT.TXT"      <-- Specify the output file
  9709.     
  9710.     If you do this, and no data is sent to the output file, the file will not
  9711.     exist.  You can check if POM failed by consulting the DOS ERRORLEVEL.
  9712.     (See your operating system manual for an explanation of ERRORLEVEL.)
  9713.     
  9714.     - If the ERRORLEVEL is 0 and the file does not exist, it means that POM
  9715.       ran successfully, but no output was sent to the file.
  9716.     
  9717.     - If the ERRORLEVEL is 1 or higher, and the file does not exist, it
  9718.       means that POM failed, or you used the HALT command before any output
  9719.       was sent to the file.
  9720.     
  9721.     If you are calling Parse-O-Matic from a program (rather than a batch file),
  9722.     you can check the error level using the facilities built in to the language
  9723.     in which the program was written.  For example, Turbo Pascal lets you
  9724.     run another program with the EXEC command, after which you can extract the
  9725.     ERRORLEVEL from the low byte of the DosExitCode variable.
  9726.     
  9727.  
  9728.  
  9729.  
  9730.  
  9731.  
  9732.  
  9733.  
  9734.  
  9735.  
  9736.  
  9737.  
  9738.                                                                             168
  9739.                             ---------------------------
  9740.                             Appending to an Output File
  9741.                             ---------------------------
  9742.     
  9743.     If you want to add data to the end of the output file, you have three
  9744.     alternatives:
  9745.     
  9746.     1)  Use wildcards, as explained in "POM and Wildcards".  In such case,
  9747.         the output file is empty when the first output line is generated
  9748.         (although see method #2 for an exception).  When processing with
  9749.         wildcards, all output is sent to the same file, unless you change
  9750.         the file with the OFILE command (see "The OFile Command").
  9751.     
  9752.     2)  Prefix the output file name with a plus sign.  This tells Parse-O-
  9753.         Matic that you want to add data to the end of the file, rather than
  9754.         starting with an empty file.  You can use this method on the command
  9755.         line:
  9756.     
  9757.         POM MYPOM.POM INPUT.TXT +C:\MYFILES\OUTPUT.TXT
  9758.     
  9759.         You can also use this method in the OFILE command:
  9760.     
  9761.         OFILE "+C:\MYFILES\OUTPUT.TXT"
  9762.     
  9763.         In these examples, we provided the full path name to the output file.
  9764.         If you do not specify a path name (e.g. OFILE "+OUTPUT.TXT"), the
  9765.         output file is placed in the current directory.
  9766.     
  9767.     3)  Use a batch file and the DOS COPY command to control the concatenation
  9768.         of output files.  This method is less convenient, but it allows you to
  9769.         bypass the addition of the new output if there is a processing error.
  9770.         Here is a sample batch file (comments appear after the arrows):
  9771.     
  9772.         @ECHO OFF                               <-- Turn batch echoing off
  9773.         IF EXIST OUTPUT.TXT DELETE OUTPUT.TXT   <-- Get rid of old output file
  9774.         POM MYPOM.POM INPUT.TXT OUTPUT.TXT      <-- Parse the input file
  9775.         IF ERRORLEVEL 1 GOTO QUIT               <-- Quit if there was an error
  9776.         IF NOT EXIST OUTPUT.TXT GOTO QUIT       <-- Quit if no output generated
  9777.         IF EXIST SAFETY.TXT DELETE SAFETY.TXT   <-- Get rid of old safety file
  9778.         RENAME MAINFILE.TXT SAFETY.TXT          <-- Backup the original file
  9779.         COPY SAVE.TXT+OUTPUT.TXT MAINFILE.TXT   <-- Add the new output
  9780.         :QUIT                                   <-- Batch file label for GOTO
  9781.     
  9782.         This method has the added advantage of creating a backup copy of the
  9783.         original output file.  If the data in the file is particularly
  9784.         important, you could place the file SAFETY.TXT on another hard drive.
  9785.     
  9786.  
  9787.  
  9788.  
  9789.  
  9790.  
  9791.  
  9792.  
  9793.                                                                             169
  9794.                              --------------------------
  9795.                              Sending Output to a Device
  9796.                              --------------------------
  9797.     
  9798.     Parse-O-Matic recognizes that an "output file" is actually a device if it
  9799.     has a colon (":") at the end of the name.  You can direct Parse-O-Matic's
  9800.     output to a standard device such as COM1: or LPT2: by specifying the device
  9801.     name accordingly. For example:
  9802.     
  9803.     POM XYZ.POM INPUT.TXT LPT1:
  9804.     
  9805.     This directs the output to the LPT1 printer.
  9806.     
  9807.     Parse-O-Matic can detect a "Not Ready" condition in most cases.  A printer
  9808.     is Not Ready when it is offline, out of paper, or its print buffer is full.
  9809.     
  9810.     If a Not Ready condition occurs, the following happens:
  9811.     
  9812.     - If you are running in Quiet Mode (/Q on the POM command line), a Not
  9813.       Ready condition terminates Parse-O-Matic with a DOS ERRORLEVEL of 243.
  9814.     
  9815.     - If you are not running in Quiet Mode, a message box gives you the option
  9816.       of trying again, or canceling processing.  If you cancel, Parse-O-Matic
  9817.       terminates with a DOS ERRORLEVEL of 244.
  9818.     
  9819.     ---------
  9820.     COM Ports
  9821.     ---------
  9822.     
  9823.     If you are sending output to a COM port (e.g. COM1:) you should first set
  9824.     the baud rate with the DOS MODE command, or Pinnacle Software's MODEM
  9825.     program (available on our BBS and Web site).
  9826.     
  9827.     The MODEM program is particularly useful if your COM port is driving a
  9828.     modem.  Parse-O-Matic talks to the operating system's COM device driver
  9829.     rather than the modem itself, so before you send data to a modem, it is a
  9830.     good idea to use the MODEM program to check that the modem is online and
  9831.     functioning properly.
  9832.     
  9833.     If you are using a high-speed modem (9600 bps or higher) and you find that
  9834.     you sometimes lose some characters, the operating system or the modem may
  9835.     not be handling a "Not Ready" condition properly during handshaking.  In
  9836.     such case, you may find it necessary to turn off buffering (locked DTE
  9837.     speed) and run at a maximum speed of 9600 bps.  For a quick course in
  9838.     high-speed modems and buffering, see the Trouble-Shooting Guide included
  9839.     with Pinnacle Software's Sapphire Bulletin Board System (also available on
  9840.     our BBS and Web site).
  9841.     
  9842.     For an example of sending output to a COM port, see "The Pause Command".
  9843.     
  9844.  
  9845.  
  9846.  
  9847.  
  9848.                                                                             170
  9849.                                      ---------
  9850.                                      DbF Files
  9851.                                      ---------
  9852.     
  9853.     If Parse-O-Matic notices that the input file is a "DBase" file (i.e. it has
  9854.     a DBF extension -- for example:  MYFILE.DBF), it will change the way it
  9855.     processes the data.  For instance, the variable $FLINE is not defined.
  9856.     Rather, each of the fields in the database are pre-parsed.  Thus, if you
  9857.     have a DBF file containing three fields (EMPNUM, NAME, PHONE), your entire
  9858.     POM file might look like this:
  9859.     
  9860.     IGNORE DELETED "Y"
  9861.     OUTEND |{EMPNUM} {NAME} {PHONE}
  9862.     
  9863.     The DELETED variable is created automatically for each record.  If it is
  9864.     set to "Y", it means the record has been deleted from the database and is
  9865.     probably not valid.  In most cases, you will want to ignore such records.
  9866.     
  9867.     If you do not know what the field names are, you can obtain the list with
  9868.     the following POM file:
  9869.     
  9870.     TRACE DELETED
  9871.     
  9872.     Afterwards, when you inspect the trace file (POM.TRC), you will see a
  9873.     summary of all the fields.  Since there are no output commands (e.g. OUTEND
  9874.     and OUTHDG), the output file will be empty.
  9875.     
  9876.     NOTE:  Parse-O-Matic does not currently support DBF "Memo" fields.
  9877.     
  9878.  
  9879.  
  9880.  
  9881.  
  9882.  
  9883.  
  9884.  
  9885.  
  9886.  
  9887.  
  9888.  
  9889.  
  9890.  
  9891.  
  9892.  
  9893.  
  9894.  
  9895.  
  9896.  
  9897.  
  9898.  
  9899.  
  9900.  
  9901.  
  9902.  
  9903.                                                                             171
  9904.                                  -----------------
  9905.                                  POM and Wildcards
  9906.                                  -----------------
  9907.     
  9908.     You can process multiple input files with the same POM file by specifying a
  9909.     DOS "wildcard" at the DOS command prompt.  All output is then directed to
  9910.     the same output file.  For example:
  9911.     
  9912.     POM XYZ.POM *.TXT OUTPUT.TXT
  9913.     
  9914.     This runs the XYZ POM file on each file in the current directory with a TXT
  9915.     extension and sends all output to the file OUTPUT.TXT.
  9916.     
  9917.     The POM file can determine which file it is reading by using the predefined
  9918.     variable $COMMAND, which contains the current POM command line.
  9919.     
  9920.     Consider the following scenario:
  9921.     
  9922.     - You have installed POM.EXE in the directory path C:\UTILITY\POM
  9923.     - The current directory contains ABC.POM, MARK.TXT, MARY.TXT and JOHN.TXT
  9924.     - You enter the command POM ABC *.DAT OUT.TXT
  9925.     
  9926.     Parse-O-Matic runs ABC.POM against the three TXT files.  On the first input
  9927.     file, $COMMAND will look like this:
  9928.     
  9929.     C:\UTILITY\POM.EXE ABC.POM MARK.TXT OUT.TXT
  9930.     
  9931.     On the next two input files, it looks like this:
  9932.     
  9933.     C:\UTILITY\POM.EXE ABC.POM MARY.TXT OUT.TXT
  9934.     C:\UTILITY\POM.EXE ABC.POM JOHN.TXT OUT.TXT
  9935.     
  9936.     Note that the file OUT.TXT is NOT processed, even though it has a TXT
  9937.     extension.  POM will always avoid processing the output file.
  9938.     
  9939.     Let's say you wanted to concatenate both MARK.TXT and MARY.TXT, and put the
  9940.     file name at the top.  You could do it with this POM file, named ABC.POM:
  9941.     
  9942.     SET cmd = $COMMAND                <-- Get the command line
  9943.     BEGIN cmd <> lastcmd              <-- Has it changed?
  9944.       PARSE  fname cmd "2* " "3* "    <-- Extract the input file name
  9945.       SETLEN flen  fname              <-- Get length of input file name
  9946.       SET    uline = ""               <-- Initialize underline
  9947.       PAD    uline "L" "-" flen       <-- Set underline
  9948.       OUTEND lastcmd <> "" |          <-- Output a linefeed unless
  9949.       OUTEND lastcmd <> "" |          <-- this is the first file
  9950.       OUTEND |{fname}                 <-- Output the file name
  9951.       OUTEND |{uline}                 <-- Output the underline
  9952.       OUTEND |                        <-- Output a linefeed
  9953.       SET    lastcmd = $COMMAND       <-- Remember this command line
  9954.     END                               <-- End of code block
  9955.     OUTEND |{$FLINE}                  <-- Output a line from the input
  9956.     
  9957.  
  9958.                                                                             172
  9959.     You could then process MARK.TXT and MARY.TXT with this command line:
  9960.     
  9961.     POM ABC M*.TXT OUT.TXT
  9962.     
  9963.     This processes any file starting with an "M" that has a TXT extension.
  9964.     
  9965.     Another way to run the command is as follows:
  9966.     
  9967.     POM ABC M???.TXT OUT.TXT
  9968.     This processes any four-letter TXT file that starts with "M".
  9969.     
  9970.     For details about DOS wildcards, consult your operating system manual.
  9971.     
  9972.     
  9973.     
  9974.     
  9975.  
  9976.  
  9977.  
  9978.  
  9979.  
  9980.  
  9981.  
  9982.  
  9983.  
  9984.  
  9985.  
  9986.  
  9987.  
  9988.  
  9989.  
  9990.  
  9991.  
  9992.  
  9993.  
  9994.  
  9995.  
  9996.  
  9997.  
  9998.  
  9999.  
  10000.  
  10001.  
  10002.  
  10003.  
  10004.  
  10005.  
  10006.  
  10007.  
  10008.  
  10009.  
  10010.  
  10011.  
  10012.  
  10013.                                                                             173
  10014.     ============================================================================
  10015.                                OPERATIONAL TECHNIQUES
  10016.     ============================================================================
  10017.     
  10018.                            -----------------------------
  10019.                            Parse-O-Matic Job (POJ) Files
  10020.                            -----------------------------
  10021.     
  10022.     As explained earlier, a standard Parse-O-Matic command line looks like this:
  10023.     
  10024.     Format:   POM pom-file input-file output-file [optional parameters]
  10025.     Example:  POM POMFILE.POM REPORT.TXT OUTPUT.TXT
  10026.     
  10027.     You can save the command specifications in a Parse-O-Matic job (.POJ) file
  10028.     so that you do not have to type them over and over again.  A POJ file is
  10029.     essentially a single-line text file that contains the specifications.
  10030.     
  10031.     ------------
  10032.     Simple Usage
  10033.     ------------
  10034.     
  10035.     Let's say you create a text file named MYJOB.POJ which contains the
  10036.     following line:
  10037.     
  10038.       POMFILE.POM REPORT.TXT OUTPUT.TXT
  10039.     
  10040.     You can then run the parsing job with the following command:
  10041.     
  10042.       POM MYJOB.POJ
  10043.     
  10044.     This would be the same as typing:
  10045.     
  10046.       POM POMFILE.POM REPORT.TXT OUTPUT.TXT
  10047.     
  10048.     NOTE:  Do NOT include the POM command in the job file.  For example:
  10049.     
  10050.       XYZ.POM ABC.TXT DEF.TXT      <-- Correct
  10051.       POM XYZ.POM ABC.TXT DEF.TXT  <-- Incorrect; the initial POM is not needed
  10052.     
  10053.     ---------------------
  10054.     Commenting a Job File
  10055.     ---------------------
  10056.     
  10057.     The POJ file can contain explanatory comments so you can document its
  10058.     purpose:  null lines and lines that start with a semi-colon are ignored.
  10059.     Thus, the MYJOB.POJ example (described above) could also have been
  10060.     written this way:
  10061.     
  10062.       ; Sample JOB file
  10063.       POMFILE.POM REPORT.TXT OUTPUT.TXT
  10064.     
  10065.     This first line is ignored, so as far as Parse-O-Matic is concerned, the
  10066.     job file contains only one line -- the command specifications.
  10067.  
  10068.                                                                             174
  10069.     (The sample PBJ files are indented here to offset them from the descriptive
  10070.     text, but a semi-colon must appear in column one to be recognized as a
  10071.     comment.)
  10072.     
  10073.     ------------------------
  10074.     Prompting for File Names
  10075.     ------------------------
  10076.     
  10077.     Job files are especially helpful when you don't know in advance which files
  10078.     will be processed, and you would like to prompt for a file name.  This lets
  10079.     you use one POM command-line to handle different situations.
  10080.     
  10081.     Let's say you create a text file named MYJOB2.POJ, which contains the
  10082.     following lines:
  10083.     
  10084.       ; Sample prompted job file
  10085.       POMFILE.POM % OUTPUT.TXT
  10086.     
  10087.     You can then run this job with the following DOS command:
  10088.     
  10089.       POM MYJOB2.POJ
  10090.     
  10091.     or simply:
  10092.     
  10093.       POM MYJOB2
  10094.     
  10095.     Since a single command-line parameter is assumed to refer to a POJ file.
  10096.     
  10097.     The % character means "Ask the user for this file".  Since, in this example,
  10098.     the % is in the second position, Parse-O-Matic will prompt you for the name
  10099.     of the input file or mask.  (If you press Esc or enter a null name,
  10100.     processing is terminated with a warning message.)
  10101.     
  10102.     Here is another example:
  10103.     
  10104.       ; Sample prompted job file
  10105.       POMFILE.POM % %
  10106.     
  10107.     This will prompt for both the input file and output file names.
  10108.     
  10109.     Now consider this example:
  10110.     
  10111.       ; Sample prompted job file
  10112.       % % %
  10113.     
  10114.     This will prompt for the POM, input and output file names -- which is not
  10115.     particularly helpful!
  10116.     
  10117.  
  10118.  
  10119.  
  10120.  
  10121.  
  10122.  
  10123.                                                                             175
  10124.     ---------------------
  10125.     Suggesting File Names
  10126.     ---------------------
  10127.     
  10128.     A % prompt will open a box on the screen to ask you for a file name (with an
  10129.     appropriate explanation of what it required) but it will not suggest a name.
  10130.     You can "feed" Parse-O-Matic a suggested name, which you can then accept by
  10131.     hitting Enter, or modify by typing a new one.
  10132.     
  10133.     To provide this default value, place the suggested file name after the %
  10134.     character.  For example:
  10135.     
  10136.       ; Sample prompted job file, with recommended file names
  10137.       POMFILE.POM %INPUT.TXT %OUTPUT.TXT
  10138.     
  10139.     When you are asked to specify the input file name, the name INPUT.TXT will
  10140.     appear in the prompt box.  It can be accepted as-is, or changed.
  10141.     
  10142.     Incidentally, if you do not provide a suggested file name for the output
  10143.     file, Parse-O-Matic will automatically suggest the name POMOUT.TXT.
  10144.     
  10145.     
  10146.     -------------------
  10147.     Optional Parameters
  10148.     -------------------
  10149.     
  10150.     You can include optional parameters in your job file line.  For example:
  10151.     
  10152.       POMFILE.POM ABC.TXT XYZ.TXT /Q
  10153.     
  10154.     Because of the /Q parameter, this will parse ABC.TXT in "Quiet mode"
  10155.     (i.e. the processing screen will not be displayed).
  10156.     
  10157.     You can not prompt for optional parameters.
  10158.     
  10159.     Because the output file name is optional in the POM command (defaulting to
  10160.     POMOUT.TXT if it is omitted, which can then be altered in the POM file
  10161.     itself with the OFILE command), it is possible to leave out the output file
  10162.     name (or prompt) in the job file:
  10163.     
  10164.       POMFILE.POM ABC.TXT /Q
  10165.     
  10166.     This assumes that the output file name is POMOUT.TXT, just as if you had
  10167.     typed the following command at the DOS prompt:
  10168.     
  10169.       POM POMFILE.POM ABC.TXT /Q
  10170.     
  10171.  
  10172.  
  10173.  
  10174.  
  10175.  
  10176.  
  10177.  
  10178.                                                                             176
  10179.     --------
  10180.     Examples
  10181.     --------
  10182.     
  10183.     The standard Parse-O-Matic package contains two sample job files, named
  10184.     SAMPJOB1.POJ and SAMPJOB2.POJ, which demonstrate simple and prompted
  10185.     usage of job files.  Both files are self-documenting, so view or print
  10186.     them out to find out how to use them.
  10187.     
  10188.                           -------------------------------
  10189.                           Encrypted (Scrambled) POM Files
  10190.                           -------------------------------
  10191.     
  10192.     Parse-O-Matic comes with a simple encryption program (named SCRAMBLE) which
  10193.     renders a POM file unreadable to humans yet still usable by Parse-O-Matic.
  10194.     
  10195.     --------------------
  10196.     The SCRAMBLE Utility
  10197.     --------------------
  10198.     
  10199.     The format of the SCRAMBLE command (entered at the DOS prompt) is as follows:
  10200.     
  10201.     SCRAMBLE filename password
  10202.     
  10203.     The filename is the name of your POM file, which will be "scrambled" into
  10204.     a seemingly meaningless jumble of characters.  The original POM file is
  10205.     renamed with a BAK extension, so if you scramble MYFILE.POM, as in this
  10206.     command:
  10207.     
  10208.     SCRAMBLE MYFILE.POM PRIVATE
  10209.     
  10210.     then two files will be created:
  10211.     
  10212.     MYFILE.POM    The scrambled POM file
  10213.     MYFILE.BAK    The original POM file
  10214.     
  10215.     The password is a code word of six letters or more that you can use to
  10216.     unscramble the file.  To do this, simply enter the SCRAMBLE command again,
  10217.     using the same password.
  10218.     
  10219.     SCRAMBLE ignores case, so the password "SECRET" is equivalent to "Secret".
  10220.     
  10221.     If the wrong password is entered, SCRAMBLE issues a warning message, pauses
  10222.     briefly, then terminates without doing anything else.
  10223.     
  10224.     For a brief summary of SCRAMBLE, enter the following command at the DOS
  10225.     prompt:
  10226.     
  10227.     SCRAMBLE /?
  10228.     
  10229.  
  10230.  
  10231.  
  10232.  
  10233.                                                                             177
  10234.     ------------------------
  10235.     Why Scramble a POM File?
  10236.     ------------------------
  10237.     
  10238.     If you are distributing a POM application, you may not want the end-users to
  10239.     be able to tamper with the POM file.  If they alter a scrambled POM file,
  10240.     they will almost certainly render it inoperable.
  10241.     
  10242.     The encryption scheme used by SCRAMBLE (and Parse-O-Matic) is not highly
  10243.     sophisticated, so there are no export restrictions on the technology.  The
  10244.     encryption could probably be "cracked" by a professional cryptologist within
  10245.     a day.  However, it should confound regular users sufficiently that they
  10246.     will not alter, excerpt or modify your POM code.
  10247.     
  10248.     When Parse-O-Matic notices that the POM file is encrypted, it disables
  10249.     tracing.  This prevents the user from using the trace facility to get a
  10250.     listing of the POM file.
  10251.     
  10252.     ----------------------
  10253.     Support Considerations
  10254.     ----------------------
  10255.     
  10256.     The SCRAMBLE program does NOT have to be present in the Parse-O-Matic
  10257.     directory for Parse-O-Matic to read scrambled files.
  10258.     
  10259.     If you are shipping a scrambled POM file to a user, you might consider
  10260.     sending along a copy of SCRAMBLE if you think the user might have to make
  10261.     some on-site changes to the POM file.  However, in order to do this, the
  10262.     user would have to know your POM file's scrambling password. In most cases
  10263.     it is probably better to provide the user with a fresh file (direct from
  10264.     you) when changes are needed.
  10265.     
  10266.     Scrambled POM files can be used with unregistered evaluation copies of
  10267.     Parse-O-Matic, although the legal requirement remains: continued use of
  10268.     Parse-O-Matic beyond 90 days requires a license (see "Licensing").  This
  10269.     lets your client try out your Parse-O-Matic solution without paying for
  10270.     Parse-O-Matic OR seeing your POM code.
  10271.     
  10272.  
  10273.  
  10274.  
  10275.  
  10276.  
  10277.  
  10278.  
  10279.  
  10280.  
  10281.  
  10282.  
  10283.  
  10284.  
  10285.  
  10286.  
  10287.  
  10288.                                                                             178
  10289.                                     -----------
  10290.                                     Batch Files
  10291.                                     -----------
  10292.     
  10293.     The built-in batch (BAT) capability of DOS and Windows is often overlooked,
  10294.     even by seasoned computer professionals.  You can use batch files to make
  10295.     Parse-O-Matic easier to use.  Batch files are created with a text editor
  10296.     (such as DOS EDIT, or Windows Notepad).
  10297.     
  10298.     --------------------------------------
  10299.     Example #1:  Save Yourself Some Typing
  10300.     --------------------------------------
  10301.     
  10302.     Here is a simple batch file (comments appear after the arrows):
  10303.     
  10304.     @ECHO OFF                               <-- Turn off command-line echoing
  10305.     POM MYPOM.POM INPUT.TXT OUTPUT.TXT      <-- Run Parse-O-Matic
  10306.     IF ERRORLEVEL 1 GOTO QUIT               <-- Quit if an error occurred
  10307.     SEE OUTPUT.TXT                          <-- View the output file
  10308.     :QUIT                                   <-- Batch file label
  10309.     
  10310.     The advantage of this batch file is that it saves you the trouble of typing
  10311.     in the entire POM command line each time you want to parse the file.
  10312.     
  10313.     ----------------------------------------
  10314.     Example #2:  Streamline Your Development
  10315.     ----------------------------------------
  10316.     
  10317.     Here is a batch file which is useful during the development of a POM file.
  10318.     
  10319.     @ECHO OFF
  10320.     DEVELOP 50 MYPOM.POM IN.TXT C:\MYFILES\OUT.TXT
  10321.     
  10322.     This batch file calls DEVELOP.BAT (included with Parse-O-Matic), which
  10323.     displays a menu with the following options:
  10324.     
  10325.     INPUT ------ View input file
  10326.     EDIT ------- Edit POM file
  10327.     PARSE ------ Run parsing job
  10328.     OUTPUT ----- View output file
  10329.     QUIT ------- Finished
  10330.     
  10331.     This lets you do the parsing, view the result, make changes to the POM file
  10332.     if necessary, then parse again.  You will find that this technique makes
  10333.     development proceed quickly.
  10334.     
  10335.     Here is an explanation of the second line of the batch file:
  10336.     
  10337.  
  10338.  
  10339.  
  10340.  
  10341.  
  10342.  
  10343.                                                                             179
  10344.     DEVELOP 50 MYPOM.POM IN.TXT C:\MYFILES\OUT.TXT
  10345.     :       :  :         :      :
  10346.     :       :  :         :      :
  10347.     :       :  :         :      Name of output file  <-----
  10348.     :       :  :         :                                |
  10349.     :       :  :         Name of input file          <-------- See NOTE #1
  10350.     :       :  :                                          |
  10351.     :       :  Name of POM file                      <-----
  10352.     :       :
  10353.     :       Save position for menu                   <-------- See NOTE #2
  10354.     :
  10355.     Invokes the batch file DEVELOP.BAT
  10356.     
  10357.     NOTE #1:  You must provide the full path to the files (unless they are in
  10358.               the current directory) and the extension.
  10359.     
  10360.     NOTE #2:  The "save position" remembers where you were in the menu.  You
  10361.               may use values 49 to 99 to provide a "memory" for 50 different
  10362.               batch files that call DEVELOP.BAT.  (The other values are
  10363.               reserved for the Parse-O-Matic installation and tutorial
  10364.               procedures.)  If 50 is not enough, you can place additional
  10365.               batch files in another directory; the menu save file (POM.MSV)
  10366.               is always placed in the current directory.
  10367.     
  10368.     In order for DEVELOP.BAT to work correctly when you are in a directory
  10369.     other than the Parse-O-Matic directory, you must place the Parse-O-Matic
  10370.     directory in your DOS PATH (see your operating system manual for details).
  10371.     Your PATH must also include the directory to a text editor.  (In the
  10372.     original Parse-O-Matic package, DEVELOP.BAT calls up DOS EDIT.)
  10373.     
  10374.     You may find it instructive to study the file DEVELOP.BAT by loading it
  10375.     into a text editor.  The batch file contains some comments which explain
  10376.     how it works.  As mentioned in one of the comments, you may wish to change
  10377.     the text editor that the batch file calls for editing the POM file.
  10378.     
  10379.     You may also find the program PSMENU.EXE useful.  For a brief description,
  10380.     type PSMENU /? at the DOS prompt.  To study a typical menu definition file,
  10381.     enter the command SEE POM.MNU at the DOS prompt.
  10382.     
  10383.     ----------------------------------
  10384.     Example #3:  Automatic Batch Files
  10385.     ----------------------------------
  10386.     
  10387.     Let's say that each day you have a text file, named DELLIST.TXT, which
  10388.     lists the names of the files that need to be deleted:
  10389.     
  10390.     FRED.TXT
  10391.     MARY.TXT
  10392.     JOHN.TXT
  10393.     HARRY.TXT
  10394.     
  10395.     You could write a POM file (we'll call it MAKEDEL.POM) to write a batch
  10396.     file to delete the files.  It would look like this:
  10397.  
  10398.                                                                             180
  10399.     PROLOGUE
  10400.       OUTEND |@ECHO OFF
  10401.     END
  10402.     IGNORE $FLINE = "COMMAND.COM"           <-- An example of a safety feature!
  10403.     OUTEND $FLINE <> "" |DEL {$FLINE}
  10404.     
  10405.     You could automate the entire procedure with the following batch file
  10406.     (which we'll call DAILYDEL.BAT):
  10407.     
  10408.     @ECHO OFF                               <-- Turn off command-line echoing
  10409.     POM MAKEDEL.POM DELLIST.TXT TEMP.BAT    <-- Create the batch file TEMP.BAT
  10410.     IF ERRORLEVEL 1 GOTO QUIT               <-- Quit if an error occurred
  10411.     TEMP.BAT                                <-- Run the batch file
  10412.     DEL TEMP.BAT                            <-- Delete it
  10413.     :QUIT                                   <-- Batch file label
  10414.     
  10415.     The second line of DAILYDEL.BAT runs Parse-O-Matic to create a batch file
  10416.     named TEMP.BAT.  Given the input file shown earlier, TEMP.BAT would look
  10417.     like this:
  10418.     
  10419.     @ECHO OFF
  10420.     DEL FRED.TXT
  10421.     DEL MARY.TXT
  10422.     DEL JOHN.TXT
  10423.     DEL HARRY.TXT
  10424.     
  10425.     After TEMP.BAT is created, DAILYDEL.BAT runs TEMP.BAT (thus deleting all
  10426.     the files listed in DELLIST.TXT).
  10427.     
  10428.     This is only a simple example.  Parse-O-Matic's ability to create batch
  10429.     files based on input data provides you with a very powerful tool for
  10430.     automating daily administrative tasks.
  10431.     
  10432.     When you write automatic applications, you should be careful to include
  10433.     routines in both the batch files and the POM files to handle any unusual
  10434.     conditions.  In MAKEDEL.POM, we checked the file to be sure that it wasn't
  10435.     "COMMAND.COM", because if that file is deleted, your system will probably
  10436.     stop working!
  10437.     
  10438.     ---------------------------------------------------------
  10439.     Example #4:  Controlling a POM File from the Command Line
  10440.     ---------------------------------------------------------
  10441.     
  10442.     Consider the following batch file, which we will call SELECT.BAT:
  10443.     
  10444.     @ECHO OFF                          <-- Turn off command-line echoing
  10445.     IF (%1) == () GOTO ERROR           <-- Make sure we have a parameter
  10446.     SET XYZ=%1                         <-- Set the environment variable XYZ
  10447.     POM SELECT.POM INPUT.TXT OUT.TXT   <-- Run the POM file SELECT.POM
  10448.     GOTO QUIT                          <-- Jump to the QUIT label
  10449.     :ERROR                             <-+
  10450.     ECHO Missing parameter               | Error-handling routine
  10451.     PAUSE                              <-+
  10452.  
  10453.                                                                             181
  10454.     :QUIT                              <-- Batch file label
  10455.     SET XYZ=                           <-- Get rid of the environment variable
  10456.     
  10457.     SELECT.BAT can be used with this POM file, which will we name SELECT.POM:
  10458.     
  10459.     PROLOGUE
  10460.       GETENV xyz "XYZ"
  10461.     END
  10462.     OUTEND $FLINE ^ xyz |{$FLINE}
  10463.     
  10464.     You can use SELECT.BAT to output only those lines that contain the variable
  10465.     that you specify.  For example, you can enter the following command at the
  10466.     DOS prompt:
  10467.     
  10468.     SELECT MARY
  10469.     
  10470.     This will output only those lines (from INPUT.TXT) that contain "MARY".
  10471.     If you wish to ignore distinctions between uppercase and lowercase, change
  10472.     the last line of SELECT.POM accordingly:
  10473.     
  10474.     OUTEND $FLUPC ^ xyz |{$FLINE}
  10475.     
  10476.     Batch file parameters are separated by spaces on the command line, so the
  10477.     following command would not work as you might expect:
  10478.     
  10479.     SELECT MARY FRED JOHN
  10480.     
  10481.     This would set the batch variable %1 to MARY, %2 to FRED and %3 to JOHN.
  10482.     
  10483.     One way to deal with this is to eliminate the spaces when you run the
  10484.     batch file:
  10485.     
  10486.     SELECT MARY/FRED/JOHN
  10487.     
  10488.     You can then replace the OUTEND command in SELECT.POM with these lines:
  10489.     
  10490.     APPEND x xyz "/"               <-- Set the x variable to "MARY/FRED/JOHN/"
  10491.     BEGIN x <> ""                  <-- We will loop through all of the names
  10492.       PEEL y x "" "/"              <-- Move a name to the y variable
  10493.       OUTEND $FLUPC ^ y |{$FLINE}  <-- Output a line if it contains the name
  10494.     AGAIN                          <-- Go back to the BEGIN
  10495.     
  10496.     Bear in mind that the system environment space is limited.  If you have
  10497.     problems with an application like this one, refer to "The GETENV Command",
  10498.     in the section entitled "Disappearing Environment Variables".
  10499.     
  10500.  
  10501.  
  10502.  
  10503.  
  10504.  
  10505.  
  10506.  
  10507.  
  10508.                                                                             182
  10509.                                 --------------------
  10510.                                 Unattended Operation
  10511.                                 --------------------
  10512.     
  10513.     You can design applications that run themselves while you are not there.
  10514.     There are two reasons why you might want to do this:
  10515.     
  10516.     - You can run long processing jobs just before leaving work at night
  10517.     - Parse-O-Matic is useful, but it isn't very interesting to watch!
  10518.     
  10519.     Several features of Parse-O-Matic facilitate "unattended operation".
  10520.     
  10521.     - The SOUND command can alert you if something unusual happens; you don't
  10522.       have to stare at the screen to make sure that everything is working.
  10523.     
  10524.     - All error messages (which say "Press a key to continue") make a noise
  10525.       via the PC speaker (see "The Sound Command").
  10526.     
  10527.     - You can use the MSGWAIT command to let processing continue if there is
  10528.       an error (see "The MSGWAIT Command").
  10529.     
  10530.     - The processing log (see "Logging") can be used to check processing.
  10531.     
  10532.     Let's say you wanted to concatenate (add together) several enormous text
  10533.     files.  You could start with the following POM file (named ADD.POM):
  10534.     
  10535.     SET    cmd = $COMMAND
  10536.     BEGIN  cmd <> lastcmd
  10537.       SOUND  "BEEP"
  10538.       SET     lastcmd = cmd
  10539.     END
  10540.     OUTEND |{$FLINE}
  10541.     
  10542.     You could then enter the command POM ADD.POM *.TXT ALL.TXT and walk away.
  10543.     Whenever a new file is started, you will hear a beep.  When you come back,
  10544.     you can check the file POMLOG.TXT (which will be located in the same
  10545.     directory as POM.EXE).  It might look something like this:
  10546.     
  10547.     COMMAND: POM ADD.POM *.TXT ALL.TXT
  10548.     DATE:    AUG 01 1997
  10549.     
  10550.     16:39:12 JOHN.TXT opened for processing
  10551.     16:45:28 JOHN.TXT processing completed
  10552.     
  10553.     16:45:29 MARY.TXT opened for processing
  10554.     16:52:10 MARY.TXT processing completed
  10555.     
  10556.     16:52:11 FRED.TXT opened for processing
  10557.     17:03:33 FRED.TXT processing completed
  10558.     
  10559.     If you are processing multiple files, and each one uses a different POM
  10560.     file (and hence requires a separate run of Parse-O-Matic) you can write
  10561.     your batch file so that it renames the log files.  This lets you review
  10562.  
  10563.                                                                             183
  10564.     each log file later.  For example:
  10565.     
  10566.     @ECHO OFF
  10567.     POM JOHN.POM JOHN.TXT JOHN.LST
  10568.     RENAME C:\POM\POMLOG.TXT JOHN.LOG
  10569.     POM MARY.POM MARY.TXT MARY.LST
  10570.     RENAME C:\POM\POMLOG.TXT MARY.LOG
  10571.     POM FRED.POM FRED.TXT FRED.LST
  10572.     RENAME C:\POM\POMLOG.TXT FRED.LOG
  10573.     
  10574.     When processing is complete, the files JOHN.LOG, MARY.LOG and FRED.LOG
  10575.     will be available in the directory C:\POM for your inspection.
  10576.     
  10577.     Here is a slightly more sophisticated version of the batch file:
  10578.     
  10579.     @ECHO OFF
  10580.     POM JOHN.POM JOHN.TXT JOHN.LST
  10581.     IF ERRORLEVEL 1 GOTO QUIT
  10582.     RENAME C:\POM\POMLOG.TXT JOHN.LOG
  10583.     POM MARY.POM MARY.TXT MARY.LST
  10584.     IF ERRORLEVEL 1 GOTO QUIT
  10585.     RENAME C:\POM\POMLOG.TXT MARY.LOG
  10586.     POM FRED.POM FRED.TXT FRED.LST
  10587.     IF ERRORLEVEL 1 GOTO QUIT
  10588.     RENAME C:\POM\POMLOG.TXT FRED.LOG
  10589.     :QUIT
  10590.     
  10591.     The IF ERRORLEVEL lines jump to the end of the batch file if Parse-O-Matic
  10592.     generates an error of 1 or higher.  When coding batch files, remember that
  10593.     the IF ERRORLEVEL command is considered "True" if the error is the
  10594.     specified value or higher.  This means you should always test the higher
  10595.     value first.  See your operating system manual for details.
  10596.     
  10597.  
  10598.  
  10599.  
  10600.  
  10601.  
  10602.  
  10603.  
  10604.  
  10605.  
  10606.  
  10607.  
  10608.  
  10609.  
  10610.  
  10611.  
  10612.  
  10613.  
  10614.  
  10615.  
  10616.  
  10617.  
  10618.                                                                             184
  10619.                                       --------
  10620.                                       Examples
  10621.                                       --------
  10622.     
  10623.     Many of the techniques described in this manual are demonstrated by the
  10624.     examples provided with the standard Parse-O-Matic package.  To see these
  10625.     examples, switch to your Parse-O-Matic directory, type START at the DOS
  10626.     prompt, or run START.BAT from Windows or OS/2, then select TUTORIAL.
  10627.     
  10628.     
  10629.     
  10630.  
  10631.  
  10632.  
  10633.  
  10634.  
  10635.  
  10636.  
  10637.  
  10638.  
  10639.  
  10640.  
  10641.  
  10642.  
  10643.  
  10644.  
  10645.  
  10646.  
  10647.  
  10648.  
  10649.  
  10650.  
  10651.  
  10652.  
  10653.  
  10654.  
  10655.  
  10656.  
  10657.  
  10658.  
  10659.  
  10660.  
  10661.  
  10662.  
  10663.  
  10664.  
  10665.  
  10666.  
  10667.  
  10668.  
  10669.  
  10670.  
  10671.  
  10672.  
  10673.                                                                             185
  10674.     ============================================================================
  10675.                              OPERATIONAL CONSIDERATIONS
  10676.     ============================================================================
  10677.     
  10678.                   -----------------------------------------------
  10679.                   Running Parse-O-Matic on 8088 and 8086 Machines
  10680.                   -----------------------------------------------
  10681.     
  10682.     Parse-O-Matic is designed to run on 80286 machines and higher, in "protected
  10683.     mode".  If you have a pressing need to run it on an old 8088 or 8086-class
  10684.     "real mode" machine (e.g. PC or XT), we may be able to prepare a custom copy
  10685.     for you.  Contact us for details.
  10686.     
  10687.                      ------------------------------------------
  10688.                      Running Parse-O-Matic from Another Program
  10689.                      ------------------------------------------
  10690.     
  10691.     If you are calling Parse-O-Matic from a program written in a high-level
  10692.     language (such as Pascal, Delphi, C or Basic), you can check its success or
  10693.     failure by consulting the "DOS Error Level".  Most languages have built-in
  10694.     facilities to test this value.
  10695.     
  10696.     For example, Turbo Pascal lets you run another program with the EXEC
  10697.     command, after which you can extract the ERRORLEVEL from the low byte of
  10698.     the DosExitCode variable.  You can also check the DOSERROR return code
  10699.     to check for invocation errors.  Some typical errors include:
  10700.     
  10701.     Program not found, Path not found, Access denied, Not enough memory.
  10702.     
  10703.     On long parsing jobs (taking 3 seconds or more on your slowest machine),
  10704.     it is perhaps best to let the user see the processing screen rather than
  10705.     running in Quiet Mode (see "Quiet Mode").  If nothing else, it gives him
  10706.     or her something to look at, and provides assurance that the machine has
  10707.     not stopped working.
  10708.     
  10709.  
  10710.  
  10711.  
  10712.  
  10713.  
  10714.  
  10715.  
  10716.  
  10717.  
  10718.  
  10719.  
  10720.  
  10721.  
  10722.  
  10723.  
  10724.  
  10725.  
  10726.  
  10727.  
  10728.                                                                             186
  10729.                               -----------------------
  10730.                               Solving Memory Problems
  10731.                               -----------------------
  10732.     
  10733.     Parse-O-Matic does all of its work in standard memory; it does not use
  10734.     Extended or Expanded memory.  This is rarely a problem, but if you do
  10735.     somehow run out of memory, there are some steps you can take...
  10736.     
  10737.     You can often free up some extra memory by unloading unused device drivers
  10738.     and DOS TSR ("Terminate and Stay Resident") programs.  (TSR's are sometimes
  10739.     called "DOS Pop-Ups")
  10740.     
  10741.     Alternatively, most drivers and TSR's can be safely moved into high memory,
  10742.     using the LOADHIGH function in your AUTOEXEC.BAT, or the DEVICEHIGH
  10743.     function in CONFIG.SYS.  Some older drivers and TSR's will not tolerate
  10744.     this kind of relocation.
  10745.     
  10746.     
  10747.     
  10748.  
  10749.  
  10750.  
  10751.  
  10752.  
  10753.  
  10754.  
  10755.  
  10756.  
  10757.  
  10758.  
  10759.  
  10760.  
  10761.  
  10762.  
  10763.  
  10764.  
  10765.  
  10766.  
  10767.  
  10768.  
  10769.  
  10770.  
  10771.  
  10772.  
  10773.  
  10774.  
  10775.  
  10776.  
  10777.  
  10778.  
  10779.  
  10780.  
  10781.  
  10782.  
  10783.                                                                             187
  10784.     ============================================================================
  10785.                                RUNNING UNDER WINDOWS
  10786.     ============================================================================
  10787.     
  10788.                                    -------------
  10789.                                    Compatibility
  10790.                                    -------------
  10791.     
  10792.     Parse-O-Matic is a DOS program, which has a few advantages and a few minor
  10793.     disadvantages for Windows users.
  10794.     
  10795.     The primary advantage is that a Parse-O-Matic application can run on any
  10796.     PC-compatible machine, whether it is running DOS, Windows, or OS/2.
  10797.     Emulators are also available which will let you run Parse-O-Matic (and
  10798.     other DOS software) on Macintosh computers.
  10799.     
  10800.     Since Parse-O-Matic has no user interface to speak of, Windows' wonderful
  10801.     graphical environment is not particularly important.  The only operational
  10802.     difference is that to interrupt Parse-O-Matic processing, you press the Esc
  10803.     key instead of clicking on a Cancel button.
  10804.     
  10805.     Performance is a consideration if you are running Parse-O-Matic at the same
  10806.     time as 32-bit applications under Windows 95 or NT; it will slow them down
  10807.     slightly.  However, unless you are multi-tasking heavily, performance is
  10808.     not an issue because the usual bottleneck is the responsiveness and
  10809.     transfer speed of the hard disk, not the speed at which the Parse-O-Matic
  10810.     program runs.
  10811.     
  10812.                              -------------------------
  10813.                              Setting Up for Windows 95
  10814.                              -------------------------
  10815.     
  10816.     To use Parse-O-Matic under Windows 95, you need the following items, which
  10817.     are included in the standard Parse-O-Matic package:
  10818.     
  10819.     1)  The POM file (icon file POM_FILE.ICO)
  10820.     2)  A batch file (icon file BAT.ICO)
  10821.     
  10822.     These two icon files are included in the standard Parse-O-Matic package.
  10823.     You may find it helpful to copy them to your main Windows directory so
  10824.     that the associations you set for them are not lost if you install
  10825.     a new version of Parse-O-Matic and then delete the original POM directory.
  10826.     
  10827.  
  10828.  
  10829.  
  10830.  
  10831.  
  10832.  
  10833.  
  10834.  
  10835.  
  10836.  
  10837.  
  10838.                                                                             188
  10839.     ------------------------------------------
  10840.     Setting Up an Association for the POM File
  10841.     ------------------------------------------
  10842.     
  10843.     When you click on a POM file, it should call up a text editor.  To configure
  10844.     this, follow these steps:
  10845.     
  10846.     1)  Double-click on "My Computer"
  10847.     
  10848.     2)  From the pull-down menu, select View/Options
  10849.     
  10850.     3)  Dialog Box:  Options
  10851.         Click on the File Types tab
  10852.         Click on the New Type button
  10853.     
  10854.     4)  Dialog Box:  Add New File Type
  10855.         Description:  Parse-O-Matic Control File
  10856.         Associated extension:  POM
  10857.         Click on the New button
  10858.     
  10859.     5)  Dialog Box:  New Action
  10860.         Action:  &Edit
  10861.         Application used:  NOTEPAD.EXE (or the path to your favorite editor)
  10862.         Click on the OK button
  10863.     
  10864.     6)  Dialog Box:  Add New File Type
  10865.         Click on the Change Icon button
  10866.         Click on the Browse button
  10867.         File name: The full path to POM_FILE.ICO (e.g. C:\POM\POM_FILE.ICO)
  10868.         Press Enter
  10869.     
  10870.     7)  Dialog Box:  Change Icon
  10871.         Click the OK button
  10872.     
  10873.     8)  Dialog Box:  Add New File Type
  10874.         Click the Close button
  10875.     
  10876.     9)  Dialog Box: Options
  10877.         Click the Close button
  10878.     
  10879.     Once you have followed these steps, you can double-click on the POM file
  10880.     icon when you are in Windows Explorer or a file folder, and it will be
  10881.     opened with the file editor you specified in step 5.
  10882.     
  10883.  
  10884.  
  10885.  
  10886.  
  10887.  
  10888.  
  10889.  
  10890.  
  10891.  
  10892.  
  10893.                                                                             189
  10894.     ----------------------------------------------
  10895.     Setting Up an Association for a POJ (Job) File
  10896.     ----------------------------------------------
  10897.     
  10898.     When you click on a POJ file, it should call up Parse-O-Matic.  To configure
  10899.     this, follow these steps:
  10900.     
  10901.     1)  Double-click on "My Computer"
  10902.     
  10903.     2)  From the pull-down menu, select View/Options
  10904.     
  10905.     3)  Dialog Box:  Options
  10906.         Click on the File Types tab
  10907.         Click on the New Type button
  10908.     
  10909.     4)  Dialog Box:  Add New File Type
  10910.         Description:  Parse-O-Matic Control File
  10911.         Associated extension:  POJ
  10912.         Click on the New button
  10913.     
  10914.     5)  Dialog Box:  New Action
  10915.         Action:  &Open
  10916.         Application used:  The path to POM.EXE  (e.g. C:\POM\POM.EXE)
  10917.         Click on the OK button
  10918.     
  10919.     6)  Dialog Box:  Add New File Type
  10920.         Click on the Change Icon button
  10921.         Click on the Browse button
  10922.         File name: The path to POJ_FILE.ICO (e.g. C:\POM\POJ_FILE.ICO)
  10923.         Press Enter
  10924.     
  10925.     7)  Dialog Box:  Change Icon
  10926.         Click the OK button
  10927.     
  10928.     8)  Dialog Box:  Add New File Type
  10929.         Click the Close button
  10930.     
  10931.     9)  Dialog Box: Options
  10932.         Click the Close button
  10933.     
  10934.     Once you have followed these steps, you can double-click on the POJ file
  10935.     icon when you are in Windows Explorer or a file folder, and it will start
  10936.     up Parse-O-Matic and run to specified job (POJ) file.
  10937.     
  10938.  
  10939.  
  10940.  
  10941.  
  10942.  
  10943.  
  10944.  
  10945.  
  10946.  
  10947.  
  10948.                                                                             190
  10949.     -----------------------------------------------------
  10950.     Setting Up an Association for the BAT File (Optional)
  10951.     -----------------------------------------------------
  10952.     
  10953.     Windows 95 is already set up to process batch (BAT) files.  However,
  10954.     Parse-O-Matic comes with an alternative icon which is more distinctive than
  10955.     the one supplied with Windows.  (The Parse-O-Matic icon looks like a bat --
  10956.     a sonar-equipped flying critter with the undeserved bad reputation).
  10957.     
  10958.     To change the icon, follow these steps:
  10959.     
  10960.     1)  Double-click on "My Computer"
  10961.     
  10962.     2)  From the pull-down menu, select View/Options
  10963.     
  10964.     3)  Dialog Box:  Options
  10965.         On the list box, find and double-click on MS-DOS Batch File
  10966.     
  10967.     4)  Dialog Box:  Edit File Type
  10968.         Click on the Change Icon button
  10969.     
  10970.     5)  Dialog Box:  Change Icon
  10971.         Click the Browse button
  10972.         File name: The full path to BAT.ICO (e.g. C:\POM\BAT.ICO)
  10973.         Press Enter
  10974.     
  10975.     6)  Dialog Box:  Change Icon
  10976.         Click the OK button
  10977.     
  10978.     7)  Dialog Box:  Edit File Type
  10979.         Click the Close button
  10980.     
  10981.     8)  Dialog Box: Options
  10982.         Click the Close button
  10983.     
  10984.     After following this procedure, your batch (BAT) file icons will be much
  10985.     more noticeable when they appear in Windows Explorer or a file folder.  To
  10986.     edit the batch file, right-click on the icon and select Edit.  To run the
  10987.     batch file, simply double-click the icon.
  10988.     
  10989.     For a discussion of batch files, see "Batch Files".
  10990.     
  10991.  
  10992.  
  10993.  
  10994.  
  10995.  
  10996.  
  10997.  
  10998.  
  10999.  
  11000.  
  11001.  
  11002.  
  11003.                                                                             191
  11004.                            ------------------------------
  11005.                            Installing the ShowNum Utility
  11006.                            ------------------------------
  11007.     
  11008.     The ShowNum program is a small utility which converts a hex number to
  11009.     decimal and vice-versa (see "The ShowNum Utility").
  11010.     
  11011.     To install ShowNum as a Windows 95 shortcut:
  11012.     
  11013.     1)  Select "File/New/Shortcut" from the pull-down menu of any folder.
  11014.     
  11015.     2)  Specify the path name to SHOWNUM.BAT, followed by a question mark.
  11016.         For example:  C:\POM\SHOWNUM.BAT ?
  11017.         The ? means "prompt for input before calling the batch file".
  11018.     
  11019.     3)  After you have finished defining the shortcut, right-click on the icon,
  11020.         select "Properties", then the "Program" tab, and make sure the "Close
  11021.         on exit" box is checked off.
  11022.     
  11023.     You can then use ShowNum by double-clicking its icon.  You will be prompted
  11024.     to enter a number, and the answer will be displayed.
  11025.     
  11026.                               ------------------------
  11027.                               Long File Names in Win95
  11028.                               ------------------------
  11029.     
  11030.     Although Parse-O-Matic can be run under Windows 95, it will only recognize
  11031.     standard DOS file names; it does not use the long file names supported by
  11032.     Win95. You can determine the underlying DOS name of a file by checking its
  11033.     "Properties" in Windows Explorer, or by using the DIR command while in DOS
  11034.     mode.
  11035.     
  11036.     
  11037.     
  11038.  
  11039.  
  11040.  
  11041.  
  11042.  
  11043.  
  11044.  
  11045.  
  11046.  
  11047.  
  11048.  
  11049.  
  11050.  
  11051.  
  11052.  
  11053.  
  11054.  
  11055.  
  11056.  
  11057.  
  11058.                                                                             192
  11059.     ============================================================================
  11060.                                      LICENSING
  11061.     ============================================================================
  11062.     
  11063.     This product is available in several forms.  For billing and pricing
  11064.     information, view or print the file ORDER.TXT.
  11065.     
  11066.                                 ----------------------
  11067.                                 Parse-O-Matic Licenses
  11068.                                 ----------------------
  11069.     
  11070.     TRIAL COPY:  If you have a "test-drive" evaluation copy, you will see a
  11071.     "Registration Reminder Screen" when you start up the program.  You are
  11072.     entitled to evaluate this program at no cost for 3 months.  If you continue
  11073.     to use it after that, you must register your copy and purchase a license,
  11074.     as described below.
  11075.     
  11076.     SINGLE-USER LICENSE:  When you register an evaluation copy of this product,
  11077.     you will receive the latest version, plus an unlocking code that will let
  11078.     you register any new evaluation versions that we release for a period of
  11079.     two years (six years for deluxe registration).
  11080.     
  11081.     SITE/MULTI-COPY LICENSES:  If you plan to run 15 or more copies of this
  11082.     program (on a network or on separate computers), you can obtain quantity
  11083.     pricing.  For details, view or print the text file ORDER.TXT.
  11084.     
  11085.     LAN LICENSE:  Local Area Network users must purchase a license for each
  11086.     user (see "Single-User License" and "Site/Multi-Copy Licenses"), although
  11087.     they can reduce this amount if they have run-control software which sets an
  11088.     upper limit on the number of concurrent users for a given program.
  11089.     
  11090.     WAN LICENSE:  Wide Area Networks are treated like LANs, but you may find it
  11091.     more economical to purchase a Distribution License (see below).
  11092.     
  11093.     DISTRIBUTION LICENSE:  The distribution license allows you to use an
  11094.     unlimited number of copies.  You may include it in your application or
  11095.     commercial package as a utility.  The only restriction is that you may not
  11096.     distribute this document (i.e. the user manual) or its essential content.
  11097.     With this safeguard, we avoid placing ourselves in competition with you;
  11098.     the program must be used to support an application or product rather than
  11099.     being its main feature.
  11100.     
  11101.     SOURCE CODE LICENSE:  If you purchase the Turbo Pascal source code, you
  11102.     must also purchase a license for each machine that will run the modified
  11103.     program.  Those portions of the source code written by Pinnacle Software
  11104.     remain copyrighted by Pinnacle, and may not be divulged to another party.
  11105.     As an alternative to purchasing the source code, you can also contract for
  11106.     us to make custom modifications to the program.
  11107.     
  11108.     RETAIL LICENSE:  You can sell complete, registered copies of this product,
  11109.     complete with documentation, in return for royalties.  The terms depend on
  11110.     volume and advance payments. Contact us for details.
  11111.     
  11112.  
  11113.                                                                             193
  11114.                                   ---------------
  11115.                                   The SEE Utility
  11116.                                   ---------------
  11117.     
  11118.     Parse-O-Matic comes with a file view/print/extract utility known as SEE
  11119.     (SEE.EXE).  The copy included in the standard package is for single-user
  11120.     operation with an evaluation or registered copy of Parse-O-Matic.  It
  11121.     may not be distributed (even if you have purchased a Distribution License
  11122.     for Parse-O-Matic).
  11123.     
  11124.     You may purchase a registered copy of SEE (including the full manual and
  11125.     walk-through).  Multi-copy and Distribution Licenses are available.  For
  11126.     more information: phone us or link up to our Web site.
  11127.  
  11128.  
  11129.  
  11130.  
  11131.  
  11132.  
  11133.  
  11134.  
  11135.  
  11136.  
  11137.  
  11138.  
  11139.  
  11140.  
  11141.  
  11142.  
  11143.  
  11144.  
  11145.  
  11146.  
  11147.  
  11148.  
  11149.  
  11150.  
  11151.  
  11152.  
  11153.  
  11154.  
  11155.  
  11156.  
  11157.  
  11158.  
  11159.  
  11160.  
  11161.  
  11162.  
  11163.  
  11164.  
  11165.  
  11166.  
  11167.  
  11168.                                                                             194
  11169.